首页 > 解决方案 > sed 匹配和替换 2 个连续的行?

问题描述

我想匹配 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;or1!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

标签: sed

解决方案


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

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

推荐阅读