我有一个格式的文本文件(“INPUT.txt”):
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'。 我可以使用冒号replace所有换行符:
cat INPUT.txt | tr '\n' ':'
我的工作有99%完成了。 不过,我现在有一个问题。 通过用冒号代替所有换行符,我不仅在序列结尾处得到了一个无关的冒号,而且在input结尾处也丢失了回车符。 它看起来像这样:
A:B:C:D:X:Y:Z:<EOF>
现在,我需要从input结尾删除冒号。 但是,如果我试图通过'sed'来传递这个处理后的input来删除最后的冒号(现在我认为这是对'sed'的正确使用),我发现自己有第二个问题。 input不再由换行符终止! 对于所有命令,“sed”彻底失败,因为它从来没有发现第一行input的结束!
似乎在一些input的末尾添加一个换行符是一个非常非常普遍的任务,考虑到我自己很想写一个程序来做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
编辑:
纯Bash的另一种方法是:
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