我有一个格式为
的文本文件(“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'。我可以使用以下命令替换冒号的所有换行符:
cat INPUT.txt | tr '\n' ':'
我的工作完成了99%。不过,我现在遇到了问题。通过用冒号替换所有换行符,我不仅在序列的末尾得到一个无关的冒号,而且在输入结束时我也丢失了回车符。它看起来像这样:
A:B:C:D:X:Y:Z:<EOF>
现在,我需要从输入的末尾删除冒号。但是,如果我尝试通过'sed'传递这个已处理的输入来删除最后的冒号(现在,我认为,正确使用'sed'),我发现自己遇到了第二个问题。输入不再由换行符终止!对于所有命令,'sed'完全失败,因为它永远不会找到第一行输入的结尾!
似乎在某些输入的末尾附加换行符是一项非常非常常见的任务,并且考虑到我自己只是极其想要编写一个用C语言编写的程序(大约需要8行代码) ,我无法想象使用Linux内核中已有的工具来实现这一目标还不是很简单。
答案 0 :(得分:15)
这应该完成工作(cat
和echo
是不必要的):
tr '\n' ':' < INPUT.TXT | sed 's/:$/\n/'
仅使用sed
:
sed -n ':a; $ ! {N;ba}; s/\n/:/g;p' INPUT.TXT
Bash没有任何外部:
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)"
答案 1 :(得分:2)
老问题,但是
paste -sd: INPUT.txt
答案 2 :(得分:1)
这是另一个解决方案:(假设一个字符集,其中':'是 八进制72,例如ascii)
perl -l72 -pe '$\="\n" if eof' INPUT.TXT