我在这里学习sed,这里有多个命令:
(user@host)-(18:27:39)-(~/Bash_Programming)
$sed '4 { s/fox/elephant/; s/dog/cat/ }' catAndDog.txt
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown elephant jumps over the lazy cat
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
但是,如果我使用多个命令并希望将结果写入文件,我应该将 w 替换标志放在哪里?
w file = write the result of the substitution to a file
编辑:
我想将整个输出写入文件,即原始文件的副本以及所做的更改。
答案1
其实,有二 w
元素。一个是命令,另一个是标志s///
。
两者都习惯写当前模式空间到文件。
命令
例如,此w
命令将写入outfile
(制作副本):
$ printf '%s\n' AA BB CC DD EE > infile
$ sed -n 'w outfile' infile
$ cat outfile
AA
BB
CC
DD
EE
该-n
选项避免打印任何模式空间,但该w
命令会将write
每个模式(行)打印到命令后参数中的文件名w
(应该结束命令)。
相反,这只会写入一行(具有(至少)一个的行C
):
$ sed -n '/C/ w outfile' infile ; cat outfile
CC
旗帜
另一个w
元素是命令w
的标志s///
,尽管它的含义大致相同write
,但只有在命令中的替换s///
被执行时它才会被执行:
$ sed -n 's/C/X/w outfile' infile; cat outfile
XC
Q1
但是,如果我使用多个命令并希望将结果写入文件,我应该将 w 替换标志放在哪里?
由于替换标志连接到一个(特定)替换,因此应在何处使用它取决于需要记录哪个替换:
$ sed -n -e 's/B/X/w outfile' -e 's/D/Y/' infile; cat outfile
XB
请注意,每个替换必须位于单独的-e
(或单独的行)中,因为输出文件名的名称必须结束命令(需要换行符),或者可以写为:
$ sed -n -e 's/B/X/w outfile
> s/D/Y/' infile; cat outfile
XB
可以选择其他替换:
$ sed -n -e 's/B/X/' -e 's/D/Y/w outfile' infile; cat outfile
YD
或两者:
$ sed -n -e 's/B/X/w outfile' -e 's/D/Y/w outfile' infile; cat outfile
XB
YD
或者使用w
命令(不是标志)(并假设 GNU sed):
$ sed -n 's/B/X/;s/D/Y/;w outfile' infile; cat outfile
AA
XB
CC
YD
EE
Q2
我想将整个输出写入文件,即原始文件的副本以及所做的更改。
A代换标志不能写所有的文件,除非所有行都发生替换。您需要使用w
命令(假设是 bash):
$ printf 'The quick brown fox jumps over the lazy dog%.0s\n' {1..14} >catAndDog.txt
$ sed -n '4 { s/fox/elephant/ ; s/dog/cat/ } ; w outfile' catAndDog.txt
$ cat outfile
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown elephant jumps over the lazy cat
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
了解w
每个替换的标志将为每个替换打印一行,所以会发生这种情况:
$ sed -n -e '4 { s/fox/elephant/w outfile' -e 's/dog/cat/w outfile' -e '}' catAndDog.txt
$ cat outfile
The quick brown elephant jumps over the lazy dog
The quick brown elephant jumps over the lazy cat
答案2
回应:
我想将整个输出写入文件,即原始文件的副本以及所做的更改。
您可以重定向到一个文件,例如
sed '4{ s/fox/elephant/; s/dog/cat/}' infile > modified_file
或者使用标志就地修改-i
:
sed -i '4{ s/fox/elephant/; s/dog/cat/}' infile
...或从原始文件中进行备份并使用相同的原始文件名写入更改。
sed -i.backup '4{ s/fox/elephant/; s/dog/cat/}' infile
或者使用w
命令:
sed '4{ s/fox/elephant/; s/dog/cat/ }; w modified_file' infile
如果您只想编写 s
命令替换成功的行(这不是您当前所要求的),则w
可以使用该标志执行以下操作:
sed '4{ s/fox/elephant/; s/dog/cat/w modified_file
}' infile
答案3
但是,如果我使用多个命令并希望将结果写入文件,我应该将 w 替换标志放在哪里?
该w
标志必须以换行符终止,或者必须是 sed 脚本中的最后一项(包括 it 参数)。如果发现空格、注释或分号,它们将包含在文件名中。
不要混淆w
与命令替换s
( s///w
) 相关的标志和w
命令。它们很相似,但w
仅在执行替换时才使用该标志。请注意,w
根据 sed 脚本(用例),可以有条件或无条件地使用该命令。
注意:选项i
( --in-place
) 不是 POSIX 指定的。
第一个例子
prompt% sed -i.back -e "/$regex/w output" -e "/$regex/d" input
第二个例子
prompt% sed -i.back "/$regex/ {
w output
d;}" input
有人可能会遇到与您的案例有关的问题(见下文)因为在同一输入行上执行了多次替换。
prompt% sed -n '4 {
s/fox/wolf/w output
s/dog/bear/w output
}' input
仅修改了一行输入,但输出文件包含两行。
The quick brown wolf jumps over the lazy dog
The quick brown wolf jumps over the lazy bear
这个结果并不方便,因为它具有误导性。
我想将整个输出写入文件,即原始文件的副本以及所做的更改。
我的解决方案允许创建原始文件 ( ) 的备份input.back
、在原始文件 ( input
) 中应用更改并在另一个文件 ( output
) 中写入潜在的替换内容。该算法使用w
命令。
prompt% sed -i.back -nE '4!p # print line except 4th
4!d # delete line except 4th
/fox|dog/!p # print line if no "fox" or no "dog"
/fox|dog/!d # don't delete line if "fox" or "dog"
s/fox/wolf/ # substitution occurs if "fox"
s/dog/bear/ # substitution occurs if "dog"
p # if a substitution then print 4th line
w output' input # if a change then save 4th line in "output"
如果没有找到或(都没有),该命令/fox|dog/!d
立即开始下一个循环。因此,如果未找到关键字,则不会对当前行处理以下命令( 、、 )。fox
dog
s///
p
w