根据特定行上的值选择/提取列

根据特定行上的值选择/提取列

这是一个示例文本文件:

A B C D E F G
1 2 3 4 5 6 7
2 3 4 5 6 7 8
3 4 5 6 7 8 9

我想根据第三行的值提取特定列,即 2 3 4 5 6 7 8。比方说,我想提取第三行值大于 5 的所有列。将是最后 3 列。因此,我的目标是选择并生成以下内容:

E F G
5 6 7
6 7 8
7 8 9

这是我的代码:

NR==3 {
    for (i=1; i<=NF; i++) {
        if ($i > 5)   x[j++] = i
    }
}
NR>= 1 {
  for (i=0 ;  i < j-1; i++ )
     printf("%s ",$x[i])
  printf("%s\n",$x[j-1])
}

然而,这会产生以下结果:

A B C D E F G
1 2 3 4 5 6 7
6 7 8
7 8 9

我错过了什么?

答案1

你可以这样做:

code=$(
  awk '
    NR == 3 {
      for (i=1; i<=NF; i++)
        if ($i > 5) { printf "%s", sep "$" i; sep="," }
      exit sep == ""
    }' file
) &&
  awk "{print $code}" file

awk对同一个文件调用两次。第一个读取第三行来构造第二次awk调用的代码。它在处理完第三行后退出,因此不会完全读取整个文件。它输出类似 的内容$5,$6,$7,因此下一次awk调用将变为:

awk '{print $5,$6,$7}' file

答案2

我有另一个 awk 解决方案可以分享:

cat > extract.columns.awk   
BEGIN {   
  infil=ARGV[1]  
    while (getline < infil > 0)  
      if (++n==3)  
      {  
        for(i=1;i<=NF;i++)  
            if ($(i) > 5) x[++j]=i  
    }  
close(infil)    
}  
{  
    for (i=1;i<j;i++)  
    printf("%s ",$x[i])  
    printf("%s\n",$x[j])  
}  

awk -f extract.columns.awk 文件

答案3

请确保按照下面的代码提及两次文件名

awk 'NR == FNR{if(FNR == line) {for(i=1; i<=NF; i++) {if($i > lmt) a[i]} close(FILENAME)} next}
{for(i=1; i<=NF; i++) {for(i in a) {out = (out == "") ? $i : (out FS $i)}}
  print out; out=""}' line=3 lmt=5 file file

相关内容