这是一个示例文本文件:
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