考虑:
echo -e "a\nb\nc\nd\ne\nf\ng\nh" | sed '3,5a test'
Run Code Online (Sandbox Code Playgroud)
这将匹配第 3、4 和 5 行。
但我试图只匹配第 3 行和第 5 行(而不是第 4 行)。并在它们之后附加“测试”。
echo ... | sed -e '3a test' -e '5a test'
Run Code Online (Sandbox Code Playgroud)
如果操作比这种情况更复杂,那么您可以使用这样的结构:
sed 'b pattern; : action; a \
lalala
b end; : pattern; 3b action; 5b action; : end'
Run Code Online (Sandbox Code Playgroud)
即你把所有你需要的命令放在b pattern;和之间b end;。
然后在: pattern;.之后添加所有模式(行号或其他)。
发生的事情是这样的:
第一个命令跳过动作部分(如果模式位于开头并b end;直接在动作部分之前,可能更容易阅读)。
如果模式匹配,则执行跳转到操作部分。动作部分执行后跳转到最后。
我试着整理一下:
sed '3b action; 5b action; b end; : action; a \
lalala
: end'
Run Code Online (Sandbox Code Playgroud)
在一行中会像:
sed "3b idAction; 5b idAction; b; : idAction; a test"
Run Code Online (Sandbox Code Playgroud)
可移植地,您需要编写它:
sed '
3b action
5b action
b
: action
a\
lalala'
Run Code Online (Sandbox Code Playgroud)
(b没有标签分支到最后,因此您不需要显式end标签,;在标准sed实现中标签中的字符是有效的)。
与sed(见@HaukeLaging 的回答)
与awk:
$ echo -e "a\nb\nc\nd\ne\nf\ng\nh" | awk 'NR==3 || NR==5{$0=$0"\ntest"}1;'
Run Code Online (Sandbox Code Playgroud)
与perl:
$ echo -e "a\nb\nc\nd\ne\nf\ng\nh" | perl -pe '$_ .="test\n" if $. == 3 || $. == 5'
Run Code Online (Sandbox Code Playgroud)
正如 @HaukeLaging aleady 所说,这个命令可以完成你想要的操作:
sed -e'3a test' -e'5a test'
Run Code Online (Sandbox Code Playgroud)
现在,如果您想要匹配(例如 20 行),输入可能会变得相当麻烦。
在这些情况下,假设您的 shell 支持大括号扩展,您可以改用以下命令:
sed -e{3,5}'a test'
Run Code Online (Sandbox Code Playgroud)
(请注意,大括号和逗号必须保持不带引号。)
因此,shell 会将参数传递给sed-e3a test以及-e5a test传递给 sed,这正是第一个命令的作用。