【问题标题】:Turning multiple lines into one comma separated line [duplicate]将多行变成一个逗号分隔的行[重复]
【发布时间】:2013-03-23 10:25:59
【问题描述】:

我在多行中有以下数据:

foo
bar
qux
zuu
sdf
sdfasdf

我想要做的是将它们转换为一个逗号分隔的行:

foo,bar,qux,zuu,sdf,sdfasdf

最好的 unix one-liner 是什么?

【问题讨论】:

  • 如果以下解决方案没有产生所需的结果,例如仅显示最后一行的内容,您的输入中可能包含不需要的控制字符,例如\r。您可以通过将输入传送到hdhexdump 来检查。 \r 将(与\n 一起)产生两字节序列0a0d。用|sed 's/\r//g'修复。
  • 这个问题是重复的,但不是所有的答案都是重复的。

标签: linux perl unix sed awk


【解决方案1】:

使用粘贴命令:

paste -d, -s file

【讨论】:

  • 粘贴是一个很棒的命令。像冠军一样工作!
  • 但是如何为变量或管道实现呢?更新自己:使用没有价值的 -s .... |粘贴 -d, -s
  • 虽然这适用于将换行符 (\n) 转换为逗号的情况,但如果需要将换行符转换为“, ”,则似乎无法使用此方法,这是许多其他命令。
  • @NeoMorfeo 您也可以使用- 从管道中读取。例如:echo -e "1\n2\n3" | paste -d, -s -
【解决方案2】:

有很多方法可以实现。您使用的工具主要取决于您自己的偏好或经验。

使用 tr 命令:

tr '\n' ',' < somefile

使用 awk:

awk -F'\n' '{if(NR == 1) {printf $0} else {printf ","$0}}' somefile

【讨论】:

  • 你的两个命令都会生成逗号结尾
  • 是的,我可以在 awk 中修复它,但不能在 tr 中修复,请稍等。
  • awk '{printf NR==1?$0:","$0}' file
  • 酷,谢谢
  • 永远不要使用printf $0,因为如果 $0 包含任何 printf 格式字符,它将神秘地失败。 printf 的概要是printf format, data,所以请改用printf "%s", $0
【解决方案3】:

Perl 单行:

perl -pe'chomp, s/$/,/ unless eof' file

或者,如果你想更神秘:

perl '-peeof||chomp&&s/$/,/' file

【讨论】:

  • 更神秘:perl '-peeof||s|$/$|,|' file
  • sid_com,我喜欢你选择的替换分隔符:D...perl -pe 'eof or s#\n$#,#' thing
  • 好吧,更神秘的 perl:perl -l54 -pe 'eof and $\=""' 文件(如果你能容忍最后一个昏迷,你可以使用空脚本体)
【解决方案4】:

根据您的输入示例,这条 awk 行有效。 (不带逗号)

awk -vRS="" -vOFS=',' '$1=$1' file

测试:

kent$  echo "foo
bar
qux
zuu
sdf
sdfasdf"|awk -vRS="" -vOFS=',' '$1=$1' 
foo,bar,qux,zuu,sdf,sdfasdf

【讨论】:

  • 如果你想要BEGIN块中可用的变量,你只需要使用-v,稍微简洁一点awk '$1=$1' RS= OFS=, file
  • 为了清楚起见并避免在您稍后尝试在 BEGIN 块中使用变量时感到惊讶,我总是使用 -v 除非将变量设置为文件之间的不同值。仅供参考,省略 -v 和变量名之间的空格会使您的脚本不必要地特定于 gawk,因此我将使用 -v RS= 而不是 -vRS=
  • @EdMorton 感谢您的评论。 (-v 和 va 之间的“空格”)。我从你那里学到了很多技巧:)。就我个人而言,我也总是使用-v
【解决方案5】:
perl -pi.bak -e 'unless(eof){s/\n/,/g}' your_file

这将创建一个扩展名为 .bak 的原始文件的备份,然后修改原始文件

【讨论】:

    【解决方案6】:
    sed -n 's/.*/&,/;H;$x;$s/,\n/,/g;$s/\n\(.*\)/\1/;$s/\(.*\),/\1/;$p'
    

    【讨论】:

    • 太复杂了。请解释@protist。
    【解决方案7】:

    文件

    aaa
    bbb
    ccc
    ddd
    

    xargs

    cat file | xargs
    

    结果

    aaa bbb ccc ddd 
    

    xargs 改进

    cat file | xargs | sed -e 's/ /,/g'
    

    结果

    aaa,bbb,ccc,ddd 
    

    【讨论】:

    • xargs 将多行转换为以空格分隔的一行,然后 sed 将所有空格替换为 ','(或 ' ,' 如果您将使用 sed -e 's/ /\ ,/g' (顺便说一下-e可以省略)
    • 通常 xargs 不适合 t 但它可以工作:)
    • 而且它更喜欢下面的一个日常使用方式
    • 感谢一步一步!我有一个文件,每行一个条目,(fn,ln,id,status,空白行。)我需要它在 CSV 中,所以我用一个未使用的符号(sed -e's/^$/ #/') 在使用你解释的模组之前。
    • 我发现这是我正在寻找的解决方案,而不是被接受的解决方案,因为它适用于管道和多个文件,如果需要,您可以将其传递给 tr -s " " "\t"添加标签等。谢谢。
    【解决方案8】:

    xargs -a your_file | sed 's/ /,/g'

    这是一种更短的方式。

    【讨论】:

    • 除非你的行中有空格...
    • sed -e 's/ /+/g' test |xargs|sed 's/ /,/g;s/+/ /g' 这只是一个想法如何使用 xargs :)不要认为这是认真的
    猜你喜欢
    • 2019-04-02
    • 2014-08-22
    • 1970-01-01
    • 2014-03-12
    • 2023-03-22
    • 2010-10-27
    • 1970-01-01
    相关资源
    最近更新 更多