UNIX:更换新线W /结肠,保留换行符EOF
问题描述:
之前我有格式的文本文件( “INPUT.TXT”):UNIX:更换新线W /结肠,保留换行符EOF
A<LF>
B<LF>
C<LF>
D<LF>
X<LF>
Y<LF>
Z<LF>
<EOF>
,我需要重新格式化为:
A:B:C:D:X:Y:Z<LF>
<EOF>
我知道你可以用'sed'来做到这一点。有'十亿谷歌命中做'与'sed'。但我试图强调可读性,简单性以及正确工作的正确工具。 'sed'是一个消耗和隐藏换行符的行编辑器。可能不是这份工作的正确工具!
我认为这项工作的正确工具是'tr'。我可以用命令用冒号替换所有换行符:
cat INPUT.txt | tr '\n' ':'
有99%的工作完成。不过,我现在有一个问题。通过用冒号替换所有换行符,我不仅在序列结尾处得到一个无关的冒号,而且在输入结尾处也会丢失回车符。它看起来像这样:
A:B:C:D:X:Y:Z:<EOF>
现在,我需要从输入的末尾删除冒号。然而,如果我试图通过'sed'传递这个处理后的输入来删除最后的冒号(现在,我认为这是对'sed'的恰当使用),我发现自己有第二个问题。输入不再由换行符终止! 'sed'对所有命令都彻底失败,因为它从来没有发现第一行输入的结尾!
好像在一些输入的末尾添加一个换行符是一个非常非常常见的任务,并且考虑到我本人非常想写一个程序来在C中执行它(这将需要大约八行代码),我无法想象,现在还没有一种简单的方法可以在Linux内核中使用已经可用的工具。
答
这应该做的工作(cat
和echo
是不必要的):
tr '\n' ':' < INPUT.TXT | sed 's/:$/\n/'
只有sed
使用:
sed -n ':a; $ ! {N;ba}; s/\n/:/g;p' INPUT.TXT
猛砸没有任何的外部:
string=($(<INPUT.TXT))
string=${string[@]/%/:}
string=${string//: /:}
string=${string%*:}
使用循环在sh
:
colon=''
while read -r line
do
string=$string$colon$line
colon=':'
done < INPUT.TXT
使用AWK:
awk '{a=a colon $0; colon=":"} END {print a}' INPUT.TXT
或者:
awk '{printf colon $0; colon=":"} END {printf "\n" }' INPUT.TXT
编辑:
这里是纯猛砸另一种方式:
string=($(<INPUT.TXT))
saveIFS=$IFS
IFS=':'
newstring="${string[*]}"
IFS=$saveIFS
编辑2:
这里的又一方式,其确实使用echo
:
echo "$(tr '\n' ':' < INPUT.TXT | head -c -1)"
答
这里的另一个解决方案:(假定一个字符集,其中 ':' 是 八进制72,例如ascii)
perl -l72 -pe '$\="\n" if eof' INPUT.TXT
答
老问题,但是
paste -sd: INPUT.txt
我起初很困惑,为什么你作为解决方案张贴我说的确切的东西没有工作,所以我在另一台机器上试了一下。 我当时意识到我需要解决方案的Sun服务器没有使用GNU'sed'。当输入没有终止换行符时,服务器上'sed'的版本会失败,因此,如上所述,为什么我使用'echo'。 ((服务器是工作中的关键任务设备,从未失败,因此从未重新启动,更不用说在几年内更新了。)欢迎来到我的生活。) 虽然shell循环解决方案非常棒,不过。 – Maarx 2010-05-27 21:15:57
/bin/sed on Sun ... ick。/usr/xpg4/bin/sed? – 2010-05-28 16:28:08