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

reg*_*x99 3 regex unix shell sed

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

sed -n 'n;p;' filename | sed 's/aaa/bbb/'
Run Code Online (Sandbox Code Playgroud)

但这并没有保存更改.感谢您对此的帮助.

Mit*_*dir 8

试试:

sed -i '2~2 s/aaa/bbb/' filename
Run Code Online (Sandbox Code Playgroud)

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


bra*_*zzi 5

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

我将补充一点,m~n寻址方法是GNU sed扩展,可能无法在任何地方使用.例如,并非所有的Mac都有GNU sed,而且*BSD系统也可能没有它.

所以,如果你有一个像下面这样的文件:

$ cat f
1   ab
2   ad
3   ab
4   ac
5   aa
6   da
7   aa
8   ad
9   aa
Run Code Online (Sandbox Code Playgroud)

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

$ 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
Run Code Online (Sandbox Code Playgroud)

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

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

$ ls
f
$ sed -i.bkp '2,${s/a/#A#/g;n}' f
$ ls
f  f.bkp
Run Code Online (Sandbox Code Playgroud)

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