выполнить несколько команд на одном совпадении в sed - PullRequest
0 голосов
/ 05 февраля 2019

Я знаю, что могу запускать команды для совпадения в sed, например, так:

$ cat file
line1
line2
line3
line4

$ sed -e "/^line2/ s/^/# /" file
line1
# line2
line3
line4

Можно ли выполнить несколько команд, скажем s/^/#/ и s/$/ # invalid/ в одном совпадении?

Я попытался добавить их оба, но получаю сообщение об ошибке:

$ sed -e "/^line2/ s/^/# / s/$/ # /" file
sed: -e expression #1, char 18: unknown option to `s'

Я попытался использовать ;, но это, похоже, отбрасывает исходное совпадение и выполняется в каждой строке ввода:

$ sed -e "/^line2/ s/^/# / ; s/$/ # /" file
line1 #
# line2 #
line3 #
line4 #

Ответы [ 4 ]

0 голосов
/ 06 февраля 2019

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

sed '/^line2/!b;s/^/.../;s/$/.../' file

Здесь регулярное выражение отменяется с помощью команды !, а сама команда b ветвится до конца всех команд sed,Возможно, более простым примером будет:

sed ' /^lines/bjumphere;bjumpthere;:jumphere;s/^/.../;s/$/.../;:jumpthere' file

Конечно, выше также можно записать:

sed '/^line2/{s/^/.../;s/$/.../}' file

При написании одних строк, заканчивающихся новой строкой (таких как i,a, c, r, R, w и W команды) и другие команды необходимы, опция -e может быть вызвана для каждой части сценария sed, например:

sed -e '/^line2/{i\a couple of lines\ninserted before "line2"' -e '}' file

Также можно написать:

sed '/^line2/i\a couple of lines\ninserted before "line2"' file

, если нет последующих команд sed для выполнения, однако, если line2 также необходимо удалить:

sed -e '/^line2/b;!i\a couple of lines\ninserted before "line2 then line2 deleted"' -e 'd' file

Однако лучшим способом было бы использовать команду c.

sed '/^line2/c\a line changed and a line\nappended for "line2"' file
0 голосов
/ 05 февраля 2019

Вы можете попробовать с расширенным регулярным выражением:

sed -r -e '/^line2/ s/(.*)/# \1 #/' file
0 голосов
/ 05 февраля 2019

Вам не нужно несколько команд, просто замените строки, начинающиеся с line2:

sed "s/^line2.*/# & #/" file
0 голосов
/ 05 февраля 2019

РЕДАКТИРОВАТЬ 2: Если вы хотите очень точно выполнить несколько операторов при выполнении условия, вы можете использовать {..} операторы блока следующим образом (только что увидел @Tiwпредложил тоже самое в комментариях.)

sed '/^line2/ {s/^/#/; s/$/ # invalid/}'  Input_file


РЕДАКТИРОВАТЬ: Добавление еще 1 решения с sed здесь.(Я просто беру строку, которая начинается с line2 в буфере памяти \1, затем просто помещаю замещенное / new_value, добавляя # перед ним и добавляя # invalid после него)

sed '/^line2/s/\(.*\)/# \1 # invalid/'  Input_file


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

sed "/^line2/ s/^/# /;/^line2/s/$/ # invalid/"  Input_file

Что происходит в вашей попытке, вы просто делаете замену, которая происходит в каждой строке, независимо от того, начинается ли она с line2 или нетпоэтому, когда вы передаете это условие перед заменой, оно должно сработать.

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