Перемещение совпадающих строк в текстовом файле с помощью sed - PullRequest
1 голос
/ 13 марта 2019

Я пытаюсь подписаться на пост

Как переместить указанную строку в файле в другое место с помощью регулярного выражения (сценарий bash)?

к моему файлу примера

asdasd0
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd2
asdasd3
asdasd4
DEFAULTS {
asdasd6

Окончательный вывод должен выглядеть как

asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd6

Я пробовал следующее

sed "/-SRC_OUT_DIR.*/d;/DEFAULTS { /a"$(sed -n '/-SRC_OUT_DIR.*/p' test.txt)  test.txt`

но это не работает. Я получаю следующий вывод

sed:can't read =: No such file or directory
sed:can't read "/a/b/c/d/e/f/g": No such file or directory
asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR
asdasd6

Мне также интересно, почему я не могу использовать \1, \2, чтобы напечатать строку, которую нужно переместить. Я пробовал это, но ничего не печатает. Как мне написать команду sed, если мне нужно переместить несколько совпадающих строк в разные места файла?

Ответы [ 2 ]

2 голосов
/ 13 марта 2019

Вы можете сохранить соответствующую строку в hold space, delete it и затем присоединить hold hold к строке, после которой вы хотите вставить:

$ sed '/^-SRC_OUT_DIR/{h;d;};/^DEFAULTS {/G' infile
asdasd0
asdasd2
asdasd3
asdasd4
DEFAULTS {
-SRC_OUT_DIR = /a/b/c/d/e/f/g/h
asdasd6
1 голос
/ 13 марта 2019

Пока вы спрашиваете решение sed, я бы предложил использовать для этого awk.Использование некрасивого вложения множества sed команд не очень рекомендуется.Тем более, что вы прочитали свой файл дважды.

Вот awk

awk '/SRC_OUT_DIR/{t=$0;next}1;/DEFAULTS/{print t}' file

Как это работает?

awk прочитает ваш file построчно.Для каждой строки будут выполняться следующие три команды одна за другой:

  1. /SRC_OUT_DIR/{t=$0;next}: , если строка содержит подстроку, соответствующую SRC_OUT_DIR, затем сохраните строку впеременную t и перейти к строке next (не выполнять 2 и 3)
  2. 1: действие по умолчанию: вывести строку
  3. /DEFAULTS/{print t}: , если текущая строка содержит подстроку DEFAULTS, выведите строку, сохраненную в переменной t

Если вам нужно переместить несколько строк (это только перемещаетвниз):

awk '/pattern1/ {t[1]=$0;next}
     /pattern2/ {t[2]=$0;next}
     /pattern3/ {t[3]=$0;next}
     /target3/ { print t[3] }
     1
     /target1/ { print t[1] }
     /target2/ { print t[2] }' file

обратите внимание, что pattern3 будет напечатано до target3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...