我需要在输入文件中搜索并替换三个连续的换行符,并将它们从输出文件中过滤掉,以符合 Centos 4 上的 makefile 规则。我使用的是 GNU sed v4.1.2 和 GNU make v3.82。我尝试了以下变体,但迄今为止没有成功:
THREE_LINE_FEEDS := $(shell echo "\012\012\012")
SED_RULE := 's/'$(THREE_LINE_FEEDS)'//'
output.txt: input.txt
sed -r $(SED_RULE) input.txt > output.txt
使用建议的 perl,我在 shell 中遇到了这个问题(改编自我的 make 规则):
> cat input.txt | perl -e '$/ = undef; _ = <>; s/\n{3}//g; print;' > output.txt
Can't modify constant item in scalar assignment at -e line 1, near "<>;"
Execution of -e aborted due to compilation errors.
答案1
sed
每次只能看到一行,因此搜索连续的换行符将不起作用。一种方法是将所有数据推送到保留空间,然后在收集完所有输入后执行替换,例如:
sed -r -n '
$! { # When it is not the last line
1 { h } # Replace hold space with first line
1! { H } # Otherwise append to hold space
}
$ { # When last line reached
H # Append it to hold space
g # Replace pattern space with hold space
s/\n{3}//g # Remove all occurrences of \n{3}
p # Print pattern space
}
' input.txt
这是一个使用 的更简单的选项perl
,但工作方式相同:
perl -e '
$/ = undef; # Slurp mode, read whole file
$_ = <>; # Read file to $_
s/\n{3}//g; # Remove all occurrences of \n{3}
print; # Output $_
' input.txt
编辑
perl
Peter O. 建议的较短版本:
perl -0777 -pe 's/\n{3}//g' input.txt
-0777
启用 slurp 模式。-p
隐式打印结果。
答案2
对于那些感兴趣的人,这里是实际的 makefile 规则(我无法让换行符在原始文件中起作用,因此使用注释来添加文档):
# 0777 - Enables slurp mode (i.e. $/ = undef; - Slurp mode, read whole file
# $_ = <>; - Read file to $_)
# s/\n{3}//g; - Remove occurrences of \n{3}
# p - Implicitly print result (i.e. print; - Output $_)
output.txt: input.txt
$(SED) -r $(SED_RULE) input.txt | perl -0777 -pe 's/\n{3}//g' > output.txt