【问题标题】:Using AWK to sum column from different files使用 AWK 对来自不同文件的列求和
【发布时间】:2018-07-06 06:51:44
【问题描述】:

我有一堆数据,比如说 a0001.xyz 到 a0254.xyz。我想对每个文件的第 5 列求和,并将答案写入一个名为 output.txt 的文件。所以我正在寻找一个包含每个 .xyz 文件总和的单列文件。

我尝试过这样的事情:

awk -f sum.awk a0004.xyz > output.txt

sum.awk 在哪里

#sum.awk
{ sum+=$5}
END { print sum }

它给了我 a0004.xyz 文件第 5 列的总和并将其写入 output.txt。问题是当我将命令更改为:

awk -f sum.awk *.xyz > output.txt

再次,它只给了我所有 .xyz 文件中的总和之一。我该如何解决这个问题?

我希望我已经设法问清楚了

【问题讨论】:

  • 请将该示例输入的所需输出添加到您的问题中。

标签: bash awk


【解决方案1】:

这样的?

$ tail a*.xyz
==> a0001.xyz <==
1 2 3 4 5 6 7
2 3 4 5 6 7 8

==> a0254.xyz <==
3 4 5 6 7 8 9
4 5 6 7 8 9 10
$ awk '{a[FILENAME]+=$5} END {for (i in a) printf "%4d %s\n", a[i], i}' a*.xyz
  11 a0001.xyz
  15 a0254.xyz

这里的 awk 脚本将 $5 的值添加到以当前文件名命名的数组元素中。处理完所有输入后,它会逐步遍历数组并打印结果,其中键是对每个值有贡献的文件名。 awk 干净且可移植地处理文件名列表,无需管道。

【讨论】:

    【解决方案2】:

    使用 GNU Parallel 并行执行所有操作:

    parallel -k -q awk '{s+=$5} END{print FILENAME,s+0}' ::: a*xyz
    

    样本输出

    a0001.xyz 20
    a0002.xyz 40
    a0254.xyz 55
    

    注意事项:

    • -k 表示“保持输出顺序”
    • -q 表示 “请引用我的 awk 内容,因为我很懒”
    • s+0 表示将 s 视为数字,因此如果未设置,则打印 0

    或者gawk:

    gawk '{s+=$5} ENDFILE{print FILENAME,s+0; s=0}' a*xyz
    

    样本输出

    a0001.xyz 20 
    a0002.xyz 40
    a0254.xyz 55
    

    【讨论】:

    • 你也可以使用--tag来代替FILENAME。
    • 即使 *.xyz 匹配 My brother's 12" records.xyz 之类的文件,此解决方案也有效。
    【解决方案3】:

    您可以将 bash 用于:

    for file in *.mp3; do 
          awk -f sum.awk "$file"
    done > output.txt
    

    【讨论】:

      【解决方案4】:
      echo *.xyz | xargs -n 1 awk '{sum+=$5} END{print FILENAME,sum }' > output.txt
      

      输出到 output.txt(例如):

      a0001.xyz 7 a0254.xyz 12

      【讨论】:

      • 如果 *.xyz 匹配 My brother's 12" records.xyz 之类的文件,此解决方案将失败。
      【解决方案5】:

      一种选择是将每个文件的结果放入数组(由文件名索引)并在最后打印:

      awk '{a[FILENAME]+=$5} END{for(f in a) print f, a[f]}' *.xyz
      

      您可以选择将文件名捕获到变量中,并在 FNR==1 和 END 时打印:

      awk 'FNR==1 && filename{print filename, sum; sum=0} {sum+=$1;filename=FILENAME} END{print filename, sum}' *.xyz
      

      【讨论】:

      • 这行得通,但我需要从 a0001 到 a0254 列出的输出,它没有给我列出的结果
      • @BugraTuzemen,这并不是一个公平的批评,因为您没有在问题中包含“预期输出”。如果没有样本数据和它应该产生的预期输出,我们只能猜测你想要什么。
      猜你喜欢
      • 2016-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多