是否可以将多个特定行号(不是范围)与 sed 匹配?

Aqu*_*wer 9 sed patterns

考虑:

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 行)。并在它们之后附加“测试”。

Hau*_*ing 9

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;.之后添加所有模式(行号或其他)。

发生的事情是这样的:

  1. 第一个命令跳过动作部分(如果模式位于开头并b end;直接在动作部分之前,可能更容易阅读)。

  2. 如果模式匹配,则执行跳转到操作部分。动作部分执行后跳转到最后。

我试着整理一下:

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 子程序。凉爽的 (4认同)

ter*_*don 5

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)


Den*_*nis 5

正如 @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,这正是第一个命令的作用。