UNIX:用冒号替换换行符,在 EOF 之前保留换行符 [英] UNIX: Replace Newline w/ Colon, Preserving Newline Before EOF

查看:42
本文介绍了UNIX:用冒号替换换行符,在 EOF 之前保留换行符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a text file ("INPUT.txt") of the format:

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"执行此操作有 10 亿次谷歌点击.但我试图强调可读性、简单性以及使用正确的工具来完成正确的工作.'sed' 是一个使用和隐藏换行符的行编辑器.可能不是这项工作的正确工具!

I know you can do this with 'sed'. There's a billion google hits for doing this with 'sed'. But I'm trying to emphasis readability, simplicity, and using the correct tool for the correct job. 'sed' is a line editor that consumes and hides newlines. Probably not the right tool for this job!

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

I think the correct tool for this job would be 'tr'. I can replace all the newlines with colons with the command:

cat INPUT.txt | tr '\n' ':'

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

There's 99% of my work done. I have a problem, now, though. By replacing all the newlines with colons, I not only get an extraneous colon at the end of the sequence, but I also lose the carriage return at the end of the input. It looks like this:

A:B:C:D:X:Y:Z:<EOF>

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

Now, I need to remove the colon from the end of the input. However, if I attempt to pass this processed input through 'sed' to remove the final colon (which would now, I think, be a proper use of 'sed'), I find myself with a second problem. The input is no longer terminated by a newline at all! 'sed' fails outright, for all commands, because it never finds the end of the first line of input!

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

It seems like appending a newline to the end of some input is a very, very common task, and considering I myself was just sorely tempted to write a program to do it in C (which would take about eight lines of code), I can't imagine there's not already a very simple way to do this with the tools already available to you in the Linux kernel.

推荐答案

这应该可以完成工作(catecho 是不必要的):

This should do the job (cat and echo are unnecessary):

tr '\n' ':' < INPUT.TXT | sed 's/:$/\n/'

仅使用 sed:

sed -n ':a; $ ! {N;ba}; s/\n/:/g;p' INPUT.TXT

没有任何外部的 Bash:

Bash without any externals:

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 的另一种方式:

Here's another way in pure Bash:

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

编辑 2:

这是确实使用echo的另一种方式:

Here's yet another way which does use echo:

echo "$(tr '\n' ':' < INPUT.TXT | head -c -1)"

这篇关于UNIX:用冒号替换换行符,在 EOF 之前保留换行符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆