在shell命令行中将两个换行符替换为一个换行符

时间:2011-09-23 22:46:32

标签: perl shell replace sed newline

关于将多个换行符替换为一个换行符有很多问题,但没有人对我有用 我有一个文件:

first line
second line MARKER

third line MARKER
other lines

many other lines

我需要在MARKER之后将两个换行符(如果存在)替换为一个换行符。结果文件应为:

first line
second line MARKER
third line MARKER
other lines

many other lines

我试过sed ':a;N;$!ba;s/MARKER\n\n/MARKER\n/g'失败 sed对单行替换非常有用,但在换行时遇到问题。找不到\n\n

我试过perl -i -p -e 's/MARKER\n\n/MARKER\n/g'失败 这个解决方案看起来更接近,但似乎regexp没有对\n\n作出反应。

是否可以仅在\n\n之后替换MARKER,而不是替换文件中的其他\n\n
我对单行解决方案感兴趣,而不是脚本。

7 个答案:

答案 0 :(得分:3)

您的Perl解决方案不起作用,因为您正在搜索包含两个换行符的行。哪有这回事。这是一个解决方案:

perl -ne'print if !$m || !/^$/; $m = /MARKER$/;' infile > outfile

或就地:

perl -i~ -ne'print if !$m || !/^$/; $m = /MARKER$/;' file

如果您可以将整个文件加载到内存中,则可以使用

perl -0777pe's/MARKER\n\n/MARKER\n/g;' infile > outfile

perl -0777pe's/MARKER\n\K\n//g;' infile > outfile

如上所述,您可以使用-i~进行就地编辑。如果您不想进行备份,请删除~

答案 1 :(得分:3)

我认为你走在了正确的轨道上。在多行程序中,您可以将整个文件加载到单个标量中并在其上运行此替换:

s/MARKER\n\n/MARKER\n/g

获取单行将文件加载到多行字符串的技巧是在$/块中设置BEGIN。在读取输入之前,此代码将执行一次。

perl -i -pe 'BEGIN{$/=undef} s/MARKER\n\n/MARKER\n/g' input

答案 2 :(得分:2)

AWK:

kent$  cat a
first line
second line MARKER

third line MARKER
other lines

many other lines

kent$  awk 'BEGIN{RS="\x034"} {gsub(/MARKER\n\n/,"MARKER\n");printf $0}' a
first line
second line MARKER
third line MARKER
other lines

many other lines

答案 3 :(得分:1)

请参阅sed one liners

答案 4 :(得分:0)

awk '
  marker { marker = 0; if (/^$/) next }
  /MARKER/ { marker = 1 }
  { print }
'

答案 5 :(得分:0)

这可以通过非常简单的sed完成。

sed '/MARKER$/{n;/./!d}'

答案 6 :(得分:0)

这可能对您有用:

 sed '/MARKER/,//{//!d}'

说明:

删除保留MARKER行的MARKER之间的所有行。

或者:

sed '/MARKER/{n;N;//D}'

说明:

阅读MARKER之后的下一行,然后在此后附加该行。如果当前行是MARKER行,则删除上一行。