如果匹配模式,删除该行中的换行符。

11

假设模式为字符串"Love"

输入

This is some text
Love this or that
He is running like a rabbit

输出

This is some text
Love this or thatHe is running like a rabbit

我注意到使用sed删除换行符非常不方便,有什么建议吗?


2
sed 每次只能处理一行。每次开始处理一行时,它会删除换行符并将其放置在模式空间中。模式空间是所有操作发生的地方。一旦替换完成,它会放置换行符并打印到 STDOUT。要删除换行符,您需要使用 N,它将下一行附加到以 \n 分隔的模式空间中,然后可以通过替换来删除它。 - jaypal singh
你喜欢在 thatHe 之间留空格吗? - Jotne
5个回答

17

你可以使用这个:

sed '/^Love/{N;s/\n//;}' love.txt

细节:

/^Love/ 用于识别要处理的行,如果你愿意,你也可以使用/[Ll]ove/

N 添加下一行到模式空间。执行此命令后,模式空间会包含Love this or that\nHe is running like a rabbit

s/\n// 替换换行符


只会说哇,当解释时很容易,使用关键元素N是否需要{ }?@casimir-et-hippolyte - josifoski
1
@josifoski:花括号将在条件“/^Love/”为真时执行的操作括起来。 - Casimir et Hippolyte
请注意,在第一次匹配和替换后,模式空间将不会在由于N而被拉入的下一行之前包含一个换行符。因此,如果您有一个不同的模式要在下一行开头匹配,它将无法匹配。例如,请考虑输入文件“Love\nLove\nLove”的情况。第二个“Love”永远不会被匹配。 - Some Guy
1
@SomeGuy: sed ':a;/[Ll]ove[^\n]*$/{N;ba};s/\n//g' love.txt 通过一个简单的循环来附加每个连续匹配行以解决问题(这次是全局替换)。 - Casimir et Hippolyte

3

Perl:

$ perl -pe 's/^(Love[^\n]*)\n/\1/' file.txt
This is some text
Love this or thatHe is running like a rabbit

或者,如果意图仅仅集中在 \n 上,你可以基于模式使用 chomp

$ perl -pe 'chomp if /^Love/' file.txt
This is some text
Love this or thatHe is running like a rabbit

2

通过Perl语言,

$ perl -pe 's/^Love.*\K\n//' file
This is some text
Love this or thatHe is running like a rabbit

\K可以用来丢弃之前匹配到的字符。

OR

$ perl -pe '/^Love/ && s/\n//' file
This is some text
Love this or thatHe is running like a rabbit

如果一行以字符串 Love 开始,则会从该行中删除换行符。


3
如果只需要去掉换行符,请使用chomp。"perl -pe 'chomp if /^Love/' file"的意思是对文件进行处理,如果该行以"Love"开头,则去掉该行的换行符。 - jaypal singh

2
$ awk '/Love/{printf "%s ",$0;next} 1' file
This is some text
Love this or that He is running like a rabbit

释义:

  • /Love/{printf "%s ",$0;next}

    对于包含 Love 的行,使用 printf 命令打印该行内容,不换行。然后 awk 继续处理下一行。

  • 1

    对于不包含 Love 的行,按正常方式打印(换行)。1 命令是 awk 打印的简写命令。


谢谢你的解决方案,将来我会花些时间学习awk。现在我主要使用sed。 - josifoski

1
这是另一种与编程有关的awk变体:

awk '{ORS=(/Love/?FS:RS)}1' file
This is some text
Love this or that He is running like a rabbi

这会根据模式改变ORS


这里有一些其他的 awk
awk '{printf "%s%s",$0,(/Love/?FS:RS)}' file
This is some text
Love this or that He is running like a rabbit

如果一行中包含 Love,则使用分隔符 FS,否则使用 RS
这种方法也可以,但最好使用第一个。
awk '{printf "%s"(/Love/?FS:RS),$0}' file

如果您不喜欢两行之间的空格,请使用 awk '{ORS=(/Love/?"":RS)}1'。甚至可以使用这个:awk 'ORS=(/Love/?FS:RS)' - Jotne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接