关于将多个换行符替换为一个换行符有很多问题,但没有人对我有用 我有一个文件:
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
?
我对单行解决方案感兴趣,而不是脚本。
答案 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
行,则删除上一行。