sed: заменить первый экземпляр только строкой, содержащей переменную bash - PullRequest
0 голосов
/ 29 мая 2018

Это что-то вроде продолжения из Как использовать sed для замены только первого вхождения в файле? , но с более целенаправленным запросом.Для данного файла

Peach: data/file1.txt
Apple: data/file2.txt
Pear: data/file3.txt
Apple: data/file4.txt

Цель состоит в том, чтобы заменить только первую строку, содержащую Apple, новой строкой, содержащей фиксированную строку (Banana), за которой следует переменная bash.В новом выводе строка 2 теперь выглядит следующим образом:

Banana: newdata/data.txt

Вот самая последняя попытка ...

BananaVariable=newdata
sed -i -E "0,|(Apple).*|{s|(Apple:).*|Banana: "$BananaVariable"/data.txt|}" filename

Однако это приводит к ошибке:

sed: -e expression #1, char 3: unexpected  `,'

Я думаю, мне нужны двойные кавычки вокруг $ BananaVariable, чтобы он мог сбежать, чтобы он мог вставить фактическую строку вместо «BananaVariable», но я думаю, что эти двойные кавычки вызывают проблему.(ОС CentOS 7, sed - версия GNU)

Ответы [ 3 ]

0 голосов
/ 29 мая 2018

Это проще с awk:

var='newdata/data.txt'
awk -v v="$var" 'BEGIN{FS=OFS=": "}
!p && $1 == "Apple"{$1="Banana"; $2=v; p=1} 1' file

Peach: data/file1.txt
Banana: newdata/data.txt
Pear: data/file3.txt
Apple: data/file4.txt
0 голосов
/ 30 мая 2018

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

sed -i -e '0,/Apple/!b;//cBanana: '"$BananaVariable"'/data.txt' file

Если строка не находится между передней частью файла, пока строка, содержащая Apple, не будет напечатана как обычно.В противном случае измените строку, содержащую Apple, на требуемую строку, используя переменную.

0 голосов
/ 29 мая 2018

С man sed:

/regexp/
       Match lines matching the regular expression regexp.

\cregexpc
       Match  lines  matching the regular expression regexp.  The c may
       be any character.

Таким образом, в вашей исходной команде замените первые два бара | на косую черту / (эквивалентно, замените первые | на \|):

sed -i -E "0,/(Apple).*/{s|(Apple:).*|Banana: $BananaVariable/data.txt|}" filename

Вы также можете сократить команду:

sed -i -E "0,/^Apple/s|.*|Banana: $BananaVariable/data.txt|" filename

вывод:

Peach: data/file1.txt
Banana: newdata/data.txt
Pear: data/file3.txt
Apple: data/file4.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...