【问题标题】:Using Awk to create a csv line使用 awk 创建 csv 行
【发布时间】:2012-07-05 17:49:16
【问题描述】:

我是 awk 的新手,并不能完全找出最好的方法来做到这一点。 我有数千个 xml 文件,我已经使用 sed 和 awk 删除了重复项并将字段划分为单个文件中的单个列。

现在我想将列表组合成一个 csv 文件,其中一行包含多个字段。在固定数量的字段之后,我想开始新的一行。

例子

1234
2345

345678
4.23456E3
54321
654321
789

87654.100
9876

10.0
1234
2345

345678
4.23456E3
54321
654321
789

87654.100
9876

11.0

输出

1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 10.0
1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 11.0

谢谢

【问题讨论】:

    标签: sed awk


    【解决方案1】:

    是否允许使用xargs

    cat input | xargs -L13 -d'\n' | sed -e 's/ /, /g'
    

    我在这里得到这个输出:

    1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 10.0
    1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 11.0
    

    不过,这有点老套,如果您开始使用 XML,您应该考虑使用 XSLT。

    【讨论】:

    • 使用xargs -a input 而不是cat
    • @Dennis:或xargs ... < input。但我之所以使用cat,是因为他听起来好像他想在现有管道的末端放置一些东西,我希望这种用法更清晰。
    【解决方案2】:

    如果每一行都有相同数量的字段,比如 5,我会做类似的事情

    awk ' { printf("%s",$1); if (NR % 5 == 0) {printf("\n")} else {printf(",")}}' youtfile.txt

    NR 是 awk 读取的行数,% 是余数运算符。因此,如果读取的行数是 5 的倍数(在这种情况下),它将打印换行符,否则将打印逗号。

    这假设与您的示例一样,每行一个字段,并且输入中的空白行将对应于 CSV 中的空白字段。

    【讨论】:

      【解决方案3】:

      一种使用sed的方式:

      script.sed的内容:

      ## Label 'a'
      :a
      
      ## If last line, print what is left in the buffer, substituting
      ## newlines with commas.
      $ {
          s/^\n//
          s/\n/, /g
          p   
          q   
      }
      
      ## If content of buffer has 12 newlines, we have reached to the limit
      ## of the line, so remove newlines with commas, print and delete buffer
      ## overwritting it with 'b'
      /\([^\n]*\n\)\{12\}/ {
          s/^\n//
          s/\n/, /g
          p   
          b   
      }
      
      ## Here buffer has not reached to the limit of fields for each line, so
      ## append one more (N) and continue loop in label 'a'
      N
      ba
      

      像这样运行它:

      sed -nf script.sed infile
      

      输出如下:

      1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 10.0
      1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 11.0
      

      【讨论】:

        【解决方案4】:

        这可能对你有用:

        paste -sd',,,,,,,,,,,,\n' file | sed 's/,/, /g'
        1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 10.0
        1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 11.0
        

        或者这个(GNU sed):

        sed ':a;$bb;N;s/\n/&/12;Ta;:b;s/\n/, /g' file
        1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 10.0
        1234, 2345, , 345678, 4.23456E3, 54321, 654321, 789, , 87654.100, 9876, , 11.0
        

        【讨论】:

          猜你喜欢
          • 2021-09-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-05
          • 1970-01-01
          • 1970-01-01
          • 2021-11-13
          • 1970-01-01
          相关资源
          最近更新 更多