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
应用于\n
s。
这个简单的命令通过将一个 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】:tr
和 sed
曾经非常好,但在文件解析和正则表达式方面你无法击败 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<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的主要内容,如果未能解决你的问题,请参考以下文章