【问题标题】:Separate comma delimited cells (varying entries) to new rows将逗号分隔的单元格(不同的条目)分隔到新行
【发布时间】:2017-12-19 23:11:00
【问题描述】:

我有两列的 .txt 文件(制表符分隔)。第一列有多个逗号分隔的值。输入格式

a,b,c x
a     y
c,d,e z

想要的输出是

a x
b x
c x
a y
c z
d z
e z

逗号分隔的条目数在 1-40 之间变化。我尝试了以下 awk 命令,但只有在第一列中有两个逗号分隔的条目时它才有效:

awk 'BEGIN{FS="[       ,]"} {print $1, $NF; print $2, $NF}' input

我怎样才能修改上面的命令(或任何新的)可以完成这项工作。谢谢。

【问题讨论】:

    标签: shell awk sed


    【解决方案1】:

    另一个awk

    $ awk -F',| +' '{for(i=1;i<NF;i++) print $i,$NF}' 
    

    将字段分隔符设置为空格或逗号,打印所有字段(直到最后一个字段)与最后一个字段的对。

    【讨论】:

      【解决方案2】:

      Perl 来救援!

      perl -lane 'print "$F[0] $_ $F[2]" for glob "{$F[1]}"' file
      
      • -n逐行读取输入
      • -l 从输入中删除换行符并将它们添加到打印中
      • -a 将空白处的每一行拆分到 @F 数组中
      • glob 在大括号中扩展逗号分隔的列表,类似于 shell

      更新:您更改了规范(未标记任何更新)。解决方案仍然相似,只需使用

      perl -lane 'print "$_ $F[1]" for glob "{$F[0]}"' file
      

      【讨论】:

        【解决方案3】:

        awk 的 split 函数来救援:

        awk '{split($1,arr,","); for (key in arr) { print arr[key],$2 }}' input
        

        【讨论】:

        • 非常好的解决方案!谢谢
        • 您应该提到,这将由in 运算符以随机顺序打印行。
        • 这不会产生如 OP 中所示的所需输出。
        • @user3439894 - 你试过运行它吗?对于指定的输入 - 它会产生所需的确切输出。
        • 是的,我根据 OP 中的信息运行它,否则我不会说什么。输出是b x\nc x\na x\na y\nd z\ne z\nc z 而不是a x\nb x\nc x\na y\nc z\nd z\ne z,如OP 中所示。甚至 Ed Morton 也对您的回答发表了评论,“您应该提到,这将由 in 运算符以随机顺序打印行。”我尝试了 karakfa 的答案,它作为 OP 中显示的输出工作。
        【解决方案4】:
        BEGIN {
            FS = "\t"
        }
        
        NF == 2 {
            n = split($1, a, ",")
            for (i = 1; i <= n; i++) {
                print a[i], $2
            }
        }
        

        【讨论】:

          【解决方案5】:

          这可能对你有用(GNU sed):

          sed -r 's/\s+(\S+)$/ \1/;s/,(.*( \S+))$/\2\n\1/;P;D' file
          

          从当前行中删除多余的空格。将每个, 替换为一个空格,然后是当前行的最后一个字段,然后是换行符。打印当前行的第一行,删除第一行并重复。

          【讨论】:

            【解决方案6】:

            你也可以使用这个 sed

            sed -E ':A;s/([^,]*),(.*)(\t.*$)/\1\3\n\2\3/;tA' infile
            

            你得到一个分开的输出标签。

            如果你不想要这个标签:

            sed -E ':A;s/([^,]*),(.*)(\t.*$)/\1\3\n\2\3/;tA;s/\t/ /g' infile
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2022-01-21
              • 1970-01-01
              • 1970-01-01
              • 2012-01-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多