Q1

Q1

我在这里学习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立即开始下一个循环。因此,如果未找到关键字,则不会对当前行处理以下命令( 、、 )。foxdogs///pw

相关内容