3

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

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

但这不会保存更改。感谢您在这方面的帮助。

4

4 回答 4

8

尝试 :

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

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

于 2012-06-01T19:54:13.773 回答
5

@Mithrandir's answer is an excellent, correct and complete one.

I will just add that the m~n addressing method is a GNU sed extension that may not work everywhere. For example, not all Macs have GNU sed, as well as *BSD systems may not have it either.

So, if you have a file like the following one:

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

...here is a more universal solution:

$ 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

What does it do? The address of the command is 2,$, which means it will be applied to all lines between the second one (2) and the last one ($). The command in fact are two commands, treated as one because they are grouped by brackets ({ and }). The first command is the replacement s/a/#A#/g. The second one is the n command, which gets, in the current iteration, the next line, appends it to the current pattern space. So the current iteration will print the current line plus the next line, and the next iteration will process the next next line. Since I started it at the 2nd line, I am doing this process at each even line.

Of course, since you want to update the original file, you should call it with the -i flag. I would note that some of those non-GNU seds require you to give a parameter to the -i flag, which will an extension to be append to a file name. This file name is the name of a generated backup file with the old content. (So, if you call, for example, sed -i.bkp s/a/b/ myfile.txt the file myfile.txt will be altered, but another file, called myfile.txt.bkp, will be created with the old content of myfile.txt.) Since a) it is required in some places and b) it is accepted in GNU sed and c) it is a good practice nonetheless (if something go wrong, you can reuse the backup), I recommend to use it:

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

Anyway, my answer is just a complement for some specific scenarios. I would use @Mithrandir's solution, even because I am a Linux user :)

于 2012-06-01T20:33:11.727 回答
0

这可能对您有用:

sed -i 'n;s/aaa/bbb/' file
于 2012-06-01T21:09:24.543 回答
-1

用于sed -i就地编辑文件。

于 2012-06-01T19:47:22.200 回答