UNIX:使用冒号替换换行符,在EOF之前保留换行符

Maa*_*arx 10 unix newline sed append

我有一个格式的文本文件("INPUT.txt"):

A<LF>
B<LF>
C<LF>
D<LF>
X<LF>
Y<LF>
Z<LF>
<EOF>
Run Code Online (Sandbox Code Playgroud)

我需要重新格式化为:

A:B:C:D:X:Y:Z<LF>
<EOF>
Run Code Online (Sandbox Code Playgroud)

我知道你可以用'sed'做到这一点.使用'sed'进行此操作有十亿次谷歌点击率.但我正在努力强调可读性,简单性,并使用正确的工具来完成正确的工作.'sed'是一个消费和隐藏换行符的行编辑器.可能不适合这份工作!

我认为这项工作的正确工具是'tr'.我可以使用命令用冒号替换所有换行符:

cat INPUT.txt | tr '\n' ':'
Run Code Online (Sandbox Code Playgroud)

我完成了99%的工作.不过,我现在遇到了问题.通过用冒号替换所有换行符,我不仅在序列的末尾得到一个无关的冒号,而且在输入结束时我也丢失了回车符.它看起来像这样:

A:B:C:D:X:Y:Z:<EOF>
Run Code Online (Sandbox Code Playgroud)

现在,我需要从输入的末尾删除冒号.但是,如果我尝试通过'sed'传递这个已处理的输入来删除最后的冒号(现在,我认为,正确使用'sed'),我发现自己遇到了第二个问题.输入不再由换行符终止!对于所有命令,'sed'完全失败,因为它永远不会找到第一行输入的结尾!

似乎在某些输入的末尾附加换行符是一个非常非常常见的任务,并且考虑到我自己只是非常想在C中编写程序来执行此操作(这将需要大约8行代码),我可以想象一下,使用Linux内核中已有的工具,还没有一种非常简单的方法可以做到这一点.

Pau*_*ce. 16

这应该做(cat并且echo是不必要的):

tr '\n' ':' < INPUT.TXT | sed 's/:$/\n/'
Run Code Online (Sandbox Code Playgroud)

仅使用sed:

sed -n ':a; $ ! {N;ba}; s/\n/:/g;p' INPUT.TXT
Run Code Online (Sandbox Code Playgroud)

Bash没有任何外部:

string=($(<INPUT.TXT))
string=${string[@]/%/:}
string=${string//: /:}
string=${string%*:}
Run Code Online (Sandbox Code Playgroud)

使用循环sh:

colon=''
while read -r line
do
    string=$string$colon$line
    colon=':'
done < INPUT.TXT
Run Code Online (Sandbox Code Playgroud)

使用AWK:

awk '{a=a colon $0; colon=":"} END {print a}' INPUT.TXT
Run Code Online (Sandbox Code Playgroud)

要么:

awk '{printf colon $0; colon=":"} END {printf "\n" }' INPUT.TXT
Run Code Online (Sandbox Code Playgroud)

编辑:

这是纯Bash的另一种方式:

string=($(<INPUT.TXT))
saveIFS=$IFS
IFS=':'
newstring="${string[*]}"
IFS=$saveIFS
Run Code Online (Sandbox Code Playgroud)

编辑2:

这里的另一个哪种方式确实使用echo:

echo "$(tr '\n' ':' < INPUT.TXT | head -c -1)"
Run Code Online (Sandbox Code Playgroud)