shell 用逗号替换 cr\lf

Posted

技术标签:

【中文标题】shell 用逗号替换 cr\\lf【英文标题】:shell replace cr\lf by commashell 用逗号替换 cr\lf 【发布时间】:2011-06-03 10:03:55 【问题描述】:

我有 input.txt

1
2
3
4
5

我需要得到这样的 output.txt

1,2,3,4,5

怎么做?

【问题讨论】:

输出应该有什么行尾?你在问题中提到 CR\LF - 你的意思是你有一个 DOS 文本文件?并且输出应该是一个 DOS 文本文件(所以你需要一个最终的 CRLF)? 【参考方案1】:

试试这个:

tr '\n' ',' < input.txt > output.txt

【讨论】:

这处理换行符;回车呢?如果用户在 DOS 上并且它是一个文本文件,则可能无事可做 - 输入例程将 CRLF 转换为 '\n'。更严重的是,也许代码用逗号替换了最后的换行符 (CRLF)。 此解决方案在末尾留一个逗号: 作为对 Jonathon 问题的答复,我不得不将 '\n' 替换为 '\r' 以进行回车。 如果您同时拥有\r\n,您可以使用dos2unix 去除回车符,然后将此tr 应用于\ns。 这个简单的命令通过将一个 SQL 查询的输出转换为 CSV,而不是使用带有 IN 语句的子查询,为我节省了大量时间 :)【参考方案2】:

使用sed,您可以使用:

sed -e 'H;$x;s/\n/,/g;s/^,//;p;;d'

H 将模式空间附加到保持空间(将当前行保存在保持空间中)。 $... 包围仅适用于最后一行的操作。这些操作是:x 交换保持和模式空间; s/\n/,/g 用逗号替换嵌入的换行符; s/^,// 删除前导逗号(在保持空间的开头有一个换行符);和p 打印。 d 删除模式空间 - 不打印。

你也可以使用,因此:

sed -n -e 'H;$x;s/\n/,/g;s/^,//;p;'

-n 禁止默认打印,因此不再需要最终的 d

此解决方案假定 CRLF 行结尾是本地本地行结尾(因此您在 DOS 上工作),因此sed 将在打印操作中生成本地本地行结尾。如果您有 DOS 格式的输入但想要 Unix 格式(仅限 LF)输出,那么您必须更加努力 - 但您还需要在问题中明确规定。

它在 MacOS X 10.6.5 上运行良好,数字为 1..5、1..50 和 1..5000(单行输出中有 23,893 个字符);我不确定我是否愿意比这更努力。

【讨论】:

另一种方式:sed -n ':a;N;$s/\n/,/g;p;ba'(无需去掉前导逗号)。【参考方案3】:

回应@Jonathan 对@eumiro 回答的评论:

tr -s '\r\n' ',' < input.txt | sed -e 's/,$/\n/' > output.txt

【讨论】:

【参考方案4】:

trsed 曾经非常好,但在文件解析和正则表达式方面你无法击败 perl (不知道为什么人们认为 sed 和 tr 比 perl 更接近 shell...)

perl -pe 's/\n/$1,/' your_file

如果你想用纯 shell 来做,那么看看字符串匹配

$string/#substring/replacement

【讨论】:

+1 因为 tr 替换了所有字符,所以对我没有好处,如果你 cat 文件,sed 解决方案有效,但如果你 tail -f 文件,则由于某种原因失败【参考方案5】: Awk 版本: awk 'printf("%s,",$0)' input.txt awk 'BEGINORS="," print $0' input.txt 输出 - 1,2,3,4,5,

由于您要求1,2,3,4,5,与1,2,3,4,5, 相比(注意5 后面的逗号,上面的大多数解决方案还包括尾随逗号),这里还有两个带有Awk 的版本(带有wc 和@ 987654327@) 去掉最后一个逗号:

i='input.txt'; awk -v c=$(wc -l $i | cut -d' ' -f1) 'printf("%s",$0);if(NR&lt;c)printf(",")' $i

awk 'printf("%s,",$0)' input.txt | sed 's/,\s*$//'

【讨论】:

【参考方案6】:
cat input.txt | sed -e 's|$|,|' | xargs -i echo ""

【讨论】:

【参考方案7】:

使用粘贴命令。这里使用管道:

echo "1\n2\n3\n4\n5" | paste -s -d, /dev/stdin

这里是使用一个文件:

echo "1\n2\n3\n4\n5" > /tmp/input.txt
paste -s -d, /tmp/input.txt

每个手册页中,s 连接所有行,d 允许定义分隔符。

【讨论】:

【参考方案8】:

python 版本:

python -c 'import sys; print(",".join(sys.stdin.read().splitlines()))'

没有尾随逗号问题(因为join 是这样工作的),splitlines 在本地行尾拆分数据(并删除它们)。

【讨论】:

【参考方案9】:
printf "1\n2\n3" | tr '\n' ','

如果你想把它输出到一个文件中,就这样做

printf "1\n2\n3" | tr '\n' ',' > myFile

如果文件中有内容,请执行

cat myInput.txt | tr '\n' ',' > myOutput.txt

【讨论】:

以上是关于shell 用逗号替换 cr\lf的主要内容,如果未能解决你的问题,请参考以下文章

PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式

shell替换一个或多个空格为逗号

如何用<br />替换CR+LF?

用括号和逗号替换字符串中的逗号(如果它们不存在)

在 Linux 的文本文件中用逗号替换空格

如何从日期用逗号替换正斜杠[重复]