Sed命令在文件的偶数行中查找和替换

时间:2012-06-01 19:45:41

标签: regex shell unix sed

嗨,我是这个论坛的新手。我想使用SED替换文件的偶数行上的表达式。我的问题是我无法想到如何保存原始文件中的更改(即如何覆盖文件中的更改)。我尝试过:

sed -n 'n;p;' filename | sed 's/aaa/bbb/'

但这并不保存更改。感谢您对此的帮助。

4 个答案:

答案 0 :(得分:8)

尝试:

sed -i '2~2 s/aaa/bbb/' filename

-i选项告诉sed在适当的位置工作,因此不要将编辑后的版本写入stout并保留原始文件,而是将更改应用于文件。 2~2部分是sed应该应用命令的行的地址。 2~2表示只编辑偶数行。 1~2只会编辑奇数行。 5~6会编辑每第五行,从第5行开始等等......

答案 1 :(得分:5)

@ Mithrandir的答案是一个优秀,正确和完整的答案。

我只想补充说m~n寻址方法a GNU sed extension可能无处不在。例如,并非所有的Mac都有GNU sed,而且* BSD系统也可能没有它。

所以,如果你有一个类似下面的文件:

$ cat f
1   ab
2   ad
3   ab
4   ac
5   aa
6   da
7   aa
8   ad
9   aa

...这是一个更通用的解决方案:

$ sed '2,${s/a/#A#/g;n}' f
1   ab
2   #A#d
3   ab
4   #A#c
5   aa
6   d#A#
7   aa
8   #A#d
9   aa

它做什么?命令的地址为2,$,这意味着它将应用于第二个(2)和最后一个($)之间的所有行。该命令实际上是两个命令,被视为一个命令,因为它们按括号({})分组。第一个命令是替换s/a/#A#/g。第二个是n命令,它在当前迭代中获取下一行,将其附加到当前pattern space。因此,当前迭代将打印当前行加上下一行,下一次迭代将处理下一行。自从我在第二行开始,我就在每个偶数行进行这个过程。

当然,由于您要更新原始文件,因此应使用-i标志来调用它。我会注意到其中一些非GNU seds 需要你给-i标志一个参数,这个扩展名将附加到文件名。此文件名是使用旧内容生成​​的备份文件的名称。 (因此,如果您致电,sed -i.bkp s/a/b/ myfile.txt文件myfile.txt将被更改,但另一个名为myfile.txt.bkp的文件将使用创建内容myfile.txt。)因为a)它在某些地方是必需的,b)它在GNU sed中被接受而c)它是一个很好的做法(如果出了问题,你可以重复使用备份),I建议使用它:

$ ls
f
$ sed -i.bkp '2,${s/a/#A#/g;n}' f
$ ls
f  f.bkp

无论如何,我的答案只是某些特定场景的补充。我会使用@ Mithrandir的解决方案,因为我是Linux用户:)

答案 2 :(得分:0)

这可能对您有用:

sed -i 'n;s/aaa/bbb/' file

答案 3 :(得分:-1)

使用sed -i编辑文件。