reg*_*x99 3 regex unix shell sed
嗨,我是这个论坛的新手.我想使用SED替换文件的偶数行上的表达式.我的问题是我无法想到如何保存原始文件中的更改(即如何覆盖文件中的更改).我尝试过:
sed -n 'n;p;' filename | sed 's/aaa/bbb/'
Run Code Online (Sandbox Code Playgroud)
但这并没有保存更改.感谢您对此的帮助.
试试:
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行开始等...
@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用户:)