我需要以以下方式解析stdin:
(1) 所有换行符都必须用n
(文字后跟
n
)替换
(2) 除了之前的之外,不应该执行任何其他操作
我选择了awk
来做这件事,如果可能的话,我想要一个使用awk
的答案。
我想出了:
echo -ne "AnBnC" | awk '{a[NR]=$0;} END{for(i=1;i<NR;i++){printf "%s\n",a[i];};printf "%s",a[NR];}'
但它看起来很笨重。
有更好/更干净的方法吗?
带awk:
echo -ne "AnBnC" | awk 'BEGIN{FS="n"; OFS="\n"; RS=ORS=""} {$1=$1}1'
输出:
A\nB\nC
请参阅:8个强大的Awk内置变量–FS、OFS、RS、ORS、NR、NF、FILENAME、FNR
-
使用
awk
处理格式错误的文件(即不以记录分隔符结尾的文件)很棘手。 -
sed -z
是GNU专用的,它的副作用是将整个(文本)文件拖入RAM(这可能是大文件的问题)
因此,对于一个稳健且可合理移植的解决方案,我将使用perl
:
perl -pe 's/n/\n/'
我将按照的方式利用GNUAWK
来完成这项任务
echo -ne "AnBnC" | awk '{printf "%s%s",$0,RT?"\n":""}'
给出输出
AnBnC
(无换行符)
说明:我确实根据当前行上下文($0
)创建要输出的字符串,并根据n
后面的反斜杠创建空字符串,或者根据作为当前行的行终止符的RT
创建空字符串。RT
值对于除最后一行以外的所有行都是换行符,对于最后一行都是空字符串,因此当在布尔上下文中使用时,对于除最后行以外的全部行都是true。我在这里使用了所谓的三元运算符条件?
值iftrue:
值iffalse。
(在GNU Awk 5.0.1中测试)
使用GNU awk进行多字符RS:
$ echo -ne "AnBnnC" | awk -v RS='^$' -v ORS= -F'n' -v OFS='\n' '{$1=$1} 1'
AnBnnC$
这应该可以解决介于问题之间的空白行:
gecho -ne "AnBnnC" |
过{m,g,n}awk 'BEGIN { RS = "^$" ; FS = "n" ORS = "" ; OFS = "\n" } NF = NF' | gcat -b
RT
:的gawk
特定方式gawk 'BEGIN { _ = ""; ORS =__= "\n" } (ORS = RT ? __ : _)^_'