【问题标题】:Column to row translation using sed使用 sed 进行列到行转换
【发布时间】:2010-11-15 00:10:54
【问题描述】:

我正在编写一个bash 脚本来从 procmail 获取数据并生成一个输出 CSV 文件。

最后,我需要从这个翻译:

---label1: 123456
---label2: 654321
---label3: 246810
---label4: 135791
---label5: 101010

到这里:

label1,label2,label3,label4,label5
123456,654321,246810,135791,101010

我可以使用ruby 脚本轻松完成此操作,但我不想调用bash 脚本以外的其他脚本。所以我想用sed 来做这件事。

我可以像这样提取我想要的数据:

sed -nr 's/^---(\S+): (\S+)$/\1,\2/p'

但我不知道如何转置它。你能帮帮我吗?

【问题讨论】:

  • 我不明白你不使用 Ruby 的原因。您想避免使用脚本语言,因此使用了两种。你的脚本会不断增长,在你知道之前,到处都会有 for 循环、tr、awk 和 sed 调用。并且使用适当的 CSV 库也可能会有所帮助,如果不是现在,那么在您的数据中有引号或逗号的下一个工作中。我不知道 Ruby,但 Perl 有一个。
  • 问题是我不想要一个不同的文件,只需要一个 bash 脚本来进行处理。但我找到了一种在 bash 脚本中使用 ruby​​ 作为 oneliner 的方法。

标签: ruby bash csv filter sed


【解决方案1】:

你可以在 awk 中做任何事情

awk 'BEGIN{
    FS=": "
}
{ 
  gsub("---","")
  label[++c] = $1
  num[++d] =$2
}
END{
    for(i=1;i<c;i++){
        printf label[i]","
    }
    print label[c]
    for(i=1;i<d;i++){
        printf num[i]","
    }
    print num[d]    
}' file

输出

# ./test.sh
label1,label2,label3,label4,label5
123456,654321,246810,135791,101010

根据需要将输出重定向到 csv 文件

【讨论】:

    【解决方案2】:

    你可以在 shell 脚本中做这样的事情:

    猫演示 | awk -F':' '{打印 $1}' | sed -e s/'---'// | tr '\n' ',' > csv_file

    猫演示 | awk '{打印 $2}' | tr '\n' ',' >> csv_file

    【讨论】:

    • 不需要猫。将文件传递给 awk
    【解决方案3】:

    你说你需要 bash 脚本..

    #!/bin/bash 标签=`awk '/---/{printf("%s,",$1)}' file.txt ` values=`awk '/---/{printf("%s,",$2)}' file.txt ` 标签=`echo $labels|sed 's/---//g;s/\://g;s/\,$//'` values=`echo $values|sed 's/\,$//` 回声$标签 回显$值

    【讨论】:

      【解决方案4】:

      最后我使用 ruby​​ 解决了这个问题,建议购买 Dave Webb,但作为单行而不是带有以下脚本的此处文档:

      ruby -ne 'BEGIN{@head=[];@data=[]}; @head << $1 && @data << $2 if $_.match(/^---(\S+): (\S+)$/); END{puts @head.join(",");puts @data.join(",")}' $FILE
      

      我不知道我可以使用 BEGIN、END 块来设置变量并输出结果。

      【讨论】:

        【解决方案5】:

        也许这就是您要找的东西? (来自unix.com

        num=$(awk -F"," 'NR==1 { print NF }' 数据)
        打印 $num
        
        我=1
        而 (( $i > tmpdata
        (( 我 = 我 + 1 ))
        完毕
        mv tmpdata 数据

        【讨论】:

          【解决方案6】:

          如果您正在运行sed,我认为您正在调用另一个脚本。那么,如果 Ruby 更易于编写和维护,为什么不用它来编写呢?

          如果您担心有多个文件,可以将 Ruby 代码作为 here document 嵌入到 bash 脚本中(假设 Ruby 可以从标准输入读取脚本)。

          【讨论】:

          • ruby 可以从标准输入中读取脚本作为此处的文档,但随后我将标准输入作为数据丢失并且不得不打开文件。请参阅我的答案以将我的最终解决方案视为红宝石单线。
          猜你喜欢
          • 1970-01-01
          • 2016-05-02
          • 2015-12-29
          • 2013-10-04
          • 2013-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-21
          相关资源
          最近更新 更多