Подберите префикс пути и замените все разделители - PullRequest
0 голосов
/ 15 января 2020

Я бы хотел сопоставить префикс пути и заменить все разделители, используя sed.

. Рассмотрим строки следующего примера и желаемые результаты. Префикс пути - one/two, а разделитель - вперед sla sh.

one/two/three.Something => one.two.three.Something
one/two/three/four/five.Another => one.two.three.four.five.Another

До сих пор я придумал эту команду

echo one/two/three.Something | sed 's/one\/two\(.*\)\./one.two\1./g'

Как мне ее сделать приведите результаты выше, это можно сделать с помощью sed?

Ответы [ 3 ]

1 голос
/ 15 января 2020

С GNU sed вы можете использовать

sed ':a; s~^\(one\)[/.]\(two[^.]*\)/~\1.\2.~; ta;' file;

Одно предупреждение : оно также будет соответствовать one.two префиксным строкам.

Или вы также можете использовать

sed 's/^one\/two[^.]*/&\n/;h;y/\//./;G;s/\n.*\n//' file

Это правильно обрабатывает только one/two строки с префиксами.

Первая команда sed означает:

  • :a - устанавливает метку a
  • s~^\(one\)[/.]\(two[^.]*\)/~\1.\2.~ - находит следующее:
    • ^ - начало строки
    • \(one\) - Группа 1 (\1): one слово
    • [/.] - / или .
    • \(two[^.]*\) - Группа 2: two, затем 0 + символы, отличные от ., а затем
    • / - / char
  • \1.\2. - Заменяет значение группы 1 + . + Значение группы 2 + .
  • ta - метка l oop - :a, если на предыдущей итерации было совпадение.

Вторая команда sed означает

  • s/^one\/two[^.]*/&\n/ - замените one/two + 0 или более символов, отличных от . на то же значение (&), и добавьте новую строку
  • h - копирует буфер шаблонов в буфер хранения, оставляя буфер шаблонов без изменений
  • y/\//./ - заменяет каждый * 107 4 * с .
  • G - добавить пробел к пространству шаблона
  • s/\n.*\n// - удалить лишний текст между двумя введенными символами новой строки.

См. онлайн sed демо :

tests="one/two/three.Something one/two/three/four/five.Another"
for test in $tests; do
  sed ':a; s~^\(one\)[/.]\(two[^.]*\)/~\1.\2.~; ta;' <<< "$test";
  sed 's/^one\/two[^.]*/&\n/;h;y/\//./;G;s/\n.*\n//' <<< "$test"
done;

Вывод:

one.two.three.Something
one.two.three.four.five.Another
1 голос
/ 15 января 2020

Не могли бы вы попробовать следующее.

awk '/one\/two.*Something||\/one\/two.*Another/{gsub(/\//,".")} 1' Input_file

Это будет искать строку one/two до something или Another и заменить все / на . в этой строке.

Объяснение: Добавление подробного объяснения уровня для вышеуказанного кода.

awk '                                           ##Starting awk program from here.
/one\/two.*Something||\/one\/two.*Another/{     ##Checking condition if a line has one/two till Something OR one/two till Another then do following.
  gsub(/\//,".")                                ##Using global substitution to substitute all / with DOT
}
1                                               ##Mentioning 1 will print edited/non-edited lines here.
'  Input_file                                   ##Mentioning Input_file name here.
0 голосов
/ 15 января 2020

Это может работать для вас (GNU sed):

sed 's#one/two/\S\+#echo "&"|sed "s:/:.:g"#eg' file

Это решение вызывает второй вызов sed в пределах RHS замены. Первая подстановка извлекает путь, вторая - эхо, которое приводит к другому вызову sed, который заменяет / на ..

NB. Подстановки могут применяться глобально по всему файлу.

...