尝试从CSV文件的特定字段读取

时间:2020-10-21 15:04:07

标签: csv awk

提供的代码读取CSV文件并按降序打印找到的所有字符串的计数。但是,我想知道如何指定要在count中读取的字段...例如 ./example-awk.awk 1,2 file.csv将从字段1和2读取字符串并打印计数

    #!/bin/awk -f

BEGIN {
    FIELDS = ARGV[1];
    delete ARGV[1];
    FS = ", *"
}

{
    for(i = 1; i <= NF; i++)
        if(FNR != 1)
        data[++data_index] = $i
}

END {
    produce_numbers(data)

    PROCINFO["sorted_in"] = "@val_num_desc"

    for(i in freq)
        printf "%s\t%d\n", i, freq[i]
}

function produce_numbers(sortedarray)
{
    n = asort(sortedarray)

    for(i = 1 ; i <= n; i++)
    {
        freq[sortedarray[i]]++
    }
    return
}

这是当前正在使用的代码,ARGV [1]当然是指定的字段。我不确定如何存储此值以使用它。

例如./example-awk.awk 1,2 simple.csv,其中simple.csv包含

A,B,C,A
B,D,C,A
C,D,A,B
D,C,A,A

应该导致

D    3
C    2
B    2
A    1

因为它只计算字段1和2中的字符串

3 个答案:

答案 0 :(得分:5)

不要使用shebang在shell脚本中调用awk,因为这会使您无法分别使用shell和awk来达到各自的最佳性能。使用shebang调用您的shell,然后在脚本中调用awk。您也不需要为此使用仅gawk的排序功能:

Num [a]

a

答案 1 :(得分:4)

编辑(根据OP的要求): 根据OP,他/她需要使用ARGV获得解决方案,因此请按此添加解决方案(注意:cat script.awk仅写为仅显示实际awk脚本的内容。

cat script.awk
BEGIN{
  FS=","
  OFS="\t"
  for(i=1;i<(ARGC-1);i++){
     arr[ARGV[i]]
     delete ARGV[i]
  }
}   
{
  for(i in arr){ value[$i]++ }
}
END{
  PROCINFO["sorted_in"] = "@ind_str_desc"
  for(j in value){
     print j,value[j]
  }
}

现在,当我们按如下方式运行它时:

awk -f script.awk 1 2 Input_file
D       3
C       2
B       2
A       1


我的原始解决方案: 请您尝试按照显示的示例进行以下操作,编写并进行测试。这是一种通用的解决方案,其中awk程序有一个名为fields的变量,您可以在其中提及要使用的,(逗号)分隔符来处理的所有字段编号。

awk -v fields="1,2" '
BEGIN{
  FS=","
  OFS="\t"
  num=split(fields,arr,",")
  for(i=1;i<=num;i++){
    key[arr[i]]
  }
}
{
for(i in key){
  value[$i]++
 }
}
END{
  for(i in value){
    print i,value[i]
  }
}' Input_file | sort -rk1

输出如下。

D       3
C       2
B       2
A       1

答案 2 :(得分:2)

我决定本着OP尝试的精神,因为孩子们不学习孩子是否不玩(尝试ARGIND操作(不起作用)和delete ARGV[],其他一些也不起作用的东西):

$ gawk '
BEGIN {
    FS=","
    OFS="\t"
    
    split(ARGV[1],t,/,/)                     # field list picked from ARGV
    for(i in t)                              # from vals to index
        h[t[i]]
    delete ARGV[1]                           # ARGIND manipulation doesnt work
}
{
    for(i in h)                              # subset of fields processes
        a[$i]++                              # count hits
}
END {
    PROCINFO["sorted_in"]="@val_num_desc"    # ordering from OPs attempt
    for(i in a)
        print i,a[i]
}' 1,2 file

输出

D       3
B       2
C       2
A       1

您也可以放弃ARGV[]操作,并用以下内容替换BEGIN块:

$ gawk -v var=1,2 '
BEGIN {
    FS=","
    OFS="\t"
    
    split(var,t,/,/)                         # field list picked from a var
    for(i in t)                              # from vals to index
        h[t[i]]
} ... 
相关问题