【问题标题】:awk loop over all fields in one fileawk 循环遍历一个文件中的所有字段
【发布时间】:2015-01-25 02:24:39
【问题描述】:

此语句为我提供了第 1 列中唯一值的计数:

awk -F ',' '{print $1}' infile1.csv | sort | uniq -c | sort -nr > outfile1.csv

它符合我的预期(给出列中唯一值(右)的计数(左)):

117 5
 58 0
 18 4
 14 3
 11 1
  9 2

但是,现在我想创建一个循环,因此它将遍历所有列。 我试过了:

for i in {1..10} 
 do 
   awk -F ',' '{print $$i}' infile.csv | sort | uniq -c | sort -nr > outfile$i.csv
done

这不起作用(它确实生成了一个文件,但包含更多数据)。我认为 print 语句中的变量,就像我尝试使用 print $$i 一样,不是一般的东西,因为我到目前为止还没有遇到它。

我也试过这个:

awk -F ',' '{for(i=1;i<=NF;i++) infile.csv | sort | uniq -c | sort -nr}' > outfile$i.csv

但这根本不会给出任何结果(意味着 infile 和 sort 命令的语法错误)。我确定我以错误的方式使用 for 语句。

理想情况下,我希望代码找到每列的唯一值计数并将它们全部打印在同一个输出文件中。但是,我已经对运行良好的循环感到非常满意。

如果这个解释不够好,请告诉我,我会尽力澄清。

【问题讨论】:

    标签: sorting csv for-loop awk uniq


    【解决方案1】:

    您希望遍历列并在每一列中执行相同的命令。所以你所做的很好:将列名传递给awk。但是,您需要以不同的方式传递值,使其成为awk 变量:

    for i in {1..10} 
     do 
       awk -F ',' -v col=$i '{print $col}' infile.csv | sort | uniq -c | sort -nr > outfile$i.csv
                  ^^^^^^^^^^^^^^^^^^^^^^^^
    done
    

    【讨论】:

    • 非常感谢!这样就可以了。
    【解决方案2】:

    任何时候你在 shell 中编写一个循环只是为了操作文本你有错误的方法。只需在一个 awk 命令中执行此操作,例如使用 GNU awk 处理 2D 数组并排序 in(未经测试,因为您没有提供任何示例输入):

    awk -F, '
    BEGIN { PROCINFO["sorted_in"] = "@val_num_desc" }
    { for (i=1; i<=NF; i++) cnt[i][$i]++ }
    END {
        for (i=1; i<=NF; i++)
            for (val in cnt[i])
                print val, cnt[i][val] > ("outfile" i ".csv")
    }
    ' infile.csv
    

    不需要六种不同的命令、管道等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-23
      • 2014-04-24
      • 1970-01-01
      • 2021-12-09
      • 2018-10-02
      相关资源
      最近更新 更多