sed匹配并替换2个连续的行?

时间:2018-05-05 00:10:33

标签: sed

我想匹配2个连续的行然后替换它。例如这种模式: [0-9]\(.*\)\n[0-9]\(.*\) 所以基本上两行都以数字开头。 然后替换它: \2\n\1 意味着交换行内容并抛弃前导数字。 示例文件1:

 adfa
adaf
dfd
1 1a
2 2b
3 3d
adfa
sdfa
4 4a
5 5b
6 6d
7 7k

示例文件2:

 adfa
adaf
dfd
aaa
1 1a
2 2b
3 3d
sdfa
4 4a
5 5b
6 6d
7 7k

许多在线答案建议使用N;1!N;,但这不起作用。 原因是N;将从第1行开始,然后每2行读取,1!N;将从第2行开始,然后每2行读取一次。但我想要的是阅读每一行及其下一行以匹配。如果N和N + 1行匹配,我们替换这2行,然后移动到N + 3和N + 4行匹配,如果不匹配,我们移动到N + 4和N + 5 ...... 两个示例文件的预期结果如下:

2b
1a
5b
4a
7k
6d

失败的命令:

sed 'N;s%[0-9]\(.*\)\n[0-9]\(.*\)%\2\n\1%;t;d' test0.txt
 3d
 2b
 5b
 4a
 7k
 6d

sed 'N;s%[0-9]\(.*\)\n[0-9]\(.*\)%\2\n\1%;t;d' test1.txt
 2b
 1a
 5b
 4a
 7k
 6d


sed '1!N;s%[0-9]\(.*\)\n[0-9]\(.*\)%\2\n\1%;t;d' test0.txt
 2b
 1a
 6d
 5b
7 7k
sed '1!N;s%[0-9]\(.*\)\n[0-9]\(.*\)%\2\n\1%;t;d' test.txt
 3d
 2b
 6d
 5b
7 7k

2 个答案:

答案 0 :(得分:2)

如果您使用D而不是d,即删除模式空间的第一行并重复if-not-empty,那么它可以工作,例如:

sed -nE 'N; s/^[0-9] (.*)\n[0-9] (.*)/\2\n\1/; ta; D; :a; p' infile

甚至更清洁,如 @potong

所示
sed 'N;/^[0-9] \(.*\)\n[0-9] \(.*\)/!D;s//\2\n\1/' infile

输出:

2b
1a
5b
4a
7k
6d

答案 1 :(得分:1)

实现它的不完美方式

sed -nr '/^[0-9]/{N;s/.*([0-9][[:alpha:]]).*([0-9][[:alpha:]])/\2\n\1/p}'
  1. 仅当行以数字开头时才使用N
  2. 然后我们可以根据需要使用正则表达式。
  3.   

    此正则表达式由您的示例文件设计,如果文件格式发生更改,则应进行调整。