sed,如何用2行替换一行?

时间:2021-08-05 16:48:31

I am trying to replace 1 line with 2 lines using sed in debian and here is what I came up with:

我想用debian中的sed将一行替换为两行,我的想法是:

 sed -i 's/You are good/You are good\n You are the best/g' /output.txt

However, when I do this, sed kept complaining saying unknown option to `s'.

然而,当我这么做的时候,sed不停地抱怨说,‘s’是未知选项。

Anyone could help?

任何人都可以帮忙吗?

Thanks!

谢谢!

3 个解决方案

#1


8  

Try this if you're in bash:

如果你在bash:

sed -i.bak $'s/You are good/You are good\\\nYou are the best/g' /output.txt

Strange, eh? But seems to work. Maybe sed can't handle the newline correctly so it needs to be escaped with another backslash, thus \\ which will become a single \ before going to sed.

奇怪,不是吗?但似乎工作。也许sed不能正确地处理换行符,所以需要使用另一个反斜杠来转义它,因此在使用sed之前,它将变成一个单个\。

Also, note that you were not passing an extension to -i.

另外,请注意您并没有将扩展名传递给-i。


Edit

Just found another solution. As the newline needs to be escaped when passing to sed (otherwise it thinks it's a command terminator) you can actually use single quotes and a return, just insert the backslash before entering the newline.

只是发现了另一个解决方案。由于在传递给sed时需要转义换行(否则它认为它是命令终止符),实际上可以使用单引号和返回,在输入换行之前插入反斜杠。

$ echo test | sed 's/test/line\
> line'
line
line

#2


7  

Or, instead of search and replace (s command), search and append (a command)

或者,不是搜索和替换(命令),而是搜索和附加(命令)

sed -i '/Your are good/a You are the best' filename

#3


1  

EDIT:

Probably my favorite method at present is to use a special character in place of '\n'. Quoting rules get to be such a headache when you're passing around a string. But if you pack your string with, say | in place of \n and _ in place of then you have a truly portable representation you can pass to functions, etc.

可能我目前最喜欢的方法是使用一个特殊字符来代替'\n'。当你传递一个字符串时,引用规则会让你头疼。但是如果你用|代替\n和_来代替你的字符串,那么你就有了一个真正可移植的表示形式你可以传递给函数,等等。

Here's an example:

这里有一个例子:

whatAmI=$( printf "Wow oh wow\nYou are good\n"| \
             sed -e 's#\(You are \)\(good\)#\1\2|\1the best#g' | \
             tr '\n' '|' | tr ' ' '_' )

Result:

结果:

Wow_oh_wow|You_are_good|You_are_the_best|

Wow_oh_wow | You_are_good | You_are_the_best |

To "unpack" your squashed string just pass it through the same tr, but with the order reversed.

要“解包”你的压缩字符串只需通过相同的tr,但顺序颠倒。

i.e.

即。

echo "$whatAmI" | tr '|' '\n' | tr '_' ' '

Result

结果

Wow oh wow
You are good
You are the best

哇哦,哇哦,哇,你很棒,你是最棒的


In addition to the above strategies (using appen --/a and delimiting with \\\n) you can also do this:

除了上述策略(使用appen -/a和用\\n分隔),你也可以这样做:

sed -i 's/You are good/You are good'"\n"' You are the best/g' /output.txt

In a way I prefer Glenn Jackman's solution as it's truer to the intent.

在某种程度上,我更喜欢格伦·杰克曼的解决方案,因为它比意图更真实。

But I find this strategy useful as you can also use it to pass in variables in bashscripts. If you're not going to use a variable more than once, it's cleaner to do than -v, e.g.

但是我发现这个策略很有用,因为您也可以使用它在bashscripts中传递变量。如果你不打算使用一个变量超过一次,它比-v更简洁。

whatYouAre="okay"
sed -i 's/You are good/You are good'"\n"' You are '"${whatYouAre}"'/g' /output.txt

(Note: single quotes also work for the \n, but not for passing in vars, as it requires interpretation.)

(注:单引号也适用于\n,但不适用于在vars中传递,因为它需要解释)。

#1


8  

Try this if you're in bash:

如果你在bash:

sed -i.bak $'s/You are good/You are good\\\nYou are the best/g' /output.txt

Strange, eh? But seems to work. Maybe sed can't handle the newline correctly so it needs to be escaped with another backslash, thus \\ which will become a single \ before going to sed.

奇怪,不是吗?但似乎工作。也许sed不能正确地处理换行符,所以需要使用另一个反斜杠来转义它,因此在使用sed之前,它将变成一个单个\。

Also, note that you were not passing an extension to -i.

另外,请注意您并没有将扩展名传递给-i。


Edit

Just found another solution. As the newline needs to be escaped when passing to sed (otherwise it thinks it's a command terminator) you can actually use single quotes and a return, just insert the backslash before entering the newline.

只是发现了另一个解决方案。由于在传递给sed时需要转义换行(否则它认为它是命令终止符),实际上可以使用单引号和返回,在输入换行之前插入反斜杠。

$ echo test | sed 's/test/line\
> line'
line
line

#2


7  

Or, instead of search and replace (s command), search and append (a command)

或者,不是搜索和替换(命令),而是搜索和附加(命令)

sed -i '/Your are good/a You are the best' filename

#3


1  

EDIT:

Probably my favorite method at present is to use a special character in place of '\n'. Quoting rules get to be such a headache when you're passing around a string. But if you pack your string with, say | in place of \n and _ in place of then you have a truly portable representation you can pass to functions, etc.

可能我目前最喜欢的方法是使用一个特殊字符来代替'\n'。当你传递一个字符串时,引用规则会让你头疼。但是如果你用|代替\n和_来代替你的字符串,那么你就有了一个真正可移植的表示形式你可以传递给函数,等等。

Here's an example:

这里有一个例子:

whatAmI=$( printf "Wow oh wow\nYou are good\n"| \
             sed -e 's#\(You are \)\(good\)#\1\2|\1the best#g' | \
             tr '\n' '|' | tr ' ' '_' )

Result:

结果:

Wow_oh_wow|You_are_good|You_are_the_best|

Wow_oh_wow | You_are_good | You_are_the_best |

To "unpack" your squashed string just pass it through the same tr, but with the order reversed.

要“解包”你的压缩字符串只需通过相同的tr,但顺序颠倒。

i.e.

即。

echo "$whatAmI" | tr '|' '\n' | tr '_' ' '

Result

结果

Wow oh wow
You are good
You are the best

哇哦,哇哦,哇,你很棒,你是最棒的


In addition to the above strategies (using appen --/a and delimiting with \\\n) you can also do this:

除了上述策略(使用appen -/a和用\\n分隔),你也可以这样做:

sed -i 's/You are good/You are good'"\n"' You are the best/g' /output.txt

In a way I prefer Glenn Jackman's solution as it's truer to the intent.

在某种程度上,我更喜欢格伦·杰克曼的解决方案,因为它比意图更真实。

But I find this strategy useful as you can also use it to pass in variables in bashscripts. If you're not going to use a variable more than once, it's cleaner to do than -v, e.g.

但是我发现这个策略很有用,因为您也可以使用它在bashscripts中传递变量。如果你不打算使用一个变量超过一次,它比-v更简洁。

whatYouAre="okay"
sed -i 's/You are good/You are good'"\n"' You are '"${whatYouAre}"'/g' /output.txt

(Note: single quotes also work for the \n, but not for passing in vars, as it requires interpretation.)

(注:单引号也适用于\n,但不适用于在vars中传递,因为它需要解释)。