简体   繁体   中英

execute multiple commands on the same match in sed

I know I can run commands against a match in sed like so:

$ cat file
line1
line2
line3
line4

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

Is it possible to run multiple commands, say s/^/#/ and s/$/ # invalid/ on the same match?

I tried adding them both but I get an error:

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

I tried using ; but that seems to discard the initial match and execute on every line in the input:

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

EDIT2: In case you are looking very specifically to execute multiple statements when a condition has met then you could use {..} block statements as follows.(Just saw @Tiw suggested same thing in comments too.)

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


EDIT: Adding 1 more solution with sed here. (I am simply taking line which is starting with line2 in a memory buffer \\1 then simply while putting substituted/new_value adding # before it and appending # invalid after it)

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


Could you please try following.

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

What is happening in your attempt, you are simply doing substitution which is happening on each line irrespective of either it starts from line2 or not, so when you give that condition before substitution it should work then.

您可以尝试使用扩展的正则表达式:

sed -r -e '/^line2/ s/(.*)/# \1 #/' file

您不需要多个命令,只需替换以line2开头的行:

sed "s/^line2.*/# & #/" file

This might work for you (GNU sed):

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

Here the regexp is negated by using the ! command and the b command by itself branches to the end of all sed commands. Perhaps as easier example would be:

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

Of course the above can also be written:

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

When writing one liners that end in a newline (such as i , a , c , r , R , w and W commands) and further commands are wanted, the -e option may be invoked for each part of the sed script, an example:

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

Also could be written:

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

if there are no subsequent sed commands to be executed, however if line2 needed to be deleted too:

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

However a better way would be to use the c command.

sed '/^line2/c\a line changed and a line\nappended for "line2"' file

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM