我有一个包含21列的文件;
Name Grade1 Grade2 Grade3 Grade4 Grade5 .... Grade20
Zoe 60 70 NA NA NA 67
现在,我想只保留超过5等级NA的名字。 有些名称包含NA。
我知道awk可以胜任这项工作。但我不确定如何比较所有列而不必单独比较它们。
我试过了:
more input_file.txt | awk 'total = count20[$2,$3,$4,$5,$6,$7,$8,$9,$10,
$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21]++, if (($2 == "NA" || $3 == "NA" ||
$4 == "NA" || $5 == "NA" || $6 == "NA" || $7 == "NA" || $8 == "NA" || $9 == "NA"
|| $10 == "NA" || $11 == "NA" || $12 == "NA" || $13 == "NA" || $14 == "NA" ||
$15 == "NA" || $16 == "NA" || $17 == "NA" || $18 == "NA" || $19 == "NA" ||
$20 == "NA" || $21 == "NA") && total > 4) { print $1"\t"$2"\t"$3"\t"$4"\t"$5"\t"
$6"\t"$7"\t"$8"\t"$9"\t"$10"\t"$11"\t"$12"\t"$13"\t"$14"\t"$15"\t"$16"\t"$17"\t"
$18"\t"$19"\t"$20"\t"$21 }' > test.txt
它不起作用,我不确定为什么或如何更有效地做到这一点。
编辑:更准确地说,想要的输出是一个包含名称的文件,以及包含NA的列数超过5列的学生的所有列。
答案 0 :(得分:1)
awk
救援!
$ awk -F'NA' 'NF>5'
假设您的名称列不包含NA作为子字符串。使用NA作为字段分隔符并计算字段,如果有超过5个字段表示至少有5个NA,则默认操作是打印该行,因此无需指定。这将为您提供5个或更多NA的记录,如果您想要严格超过5,则将阈值更改为6.
答案 1 :(得分:1)
此命令至少打印六次包含NA
的所有行:
grep -E '(NA.*){6}' infile
如果学生的姓名也包含NA
,则可能会被绊倒。要解决此问题,您可以使用
grep -E '^[^[:blank:]]+[[:blank:]]+(NA.*){6,}' infile
在第一列之后仅计算NA
。
答案 2 :(得分:0)
这是使用awk执行此操作的一种相当基本的方法:
awk '{ count = 0; for (i = 2; i <= NF; ++i) if ($i == "NA") ++count } count > 5' file
循环遍历每个字段并检查它是否等于&#34; NA&#34;。如果是这样,它会增加该记录的总计数。当计数大于5时,将打印记录。
答案 3 :(得分:0)
它标记为perl
所以perl回答:
perl -ne 'print if (grep /^NA$/, split ) > 5'
其中:
NA
> 5
,则答案 4 :(得分:0)
使用GNU awk进行单词边界:
awk -F'\\<NA\\>' 'NF>6'
如果您的字段按标签分隔,则使用任何awk:
awk -F'\tNA(\t|$)' 'NF>6'
任何POSIX awk表示字段之间的任何类型的空格:
awk -F'[[:space:]]NA([[:space:]]|$)' 'NF>6'
答案 5 :(得分:0)
在Perl中,只计算等于NA
perl -ne 'print if 5 <= grep { $_ eq "NA" } split' test.txt
或者,正如Tom Fenech在评论中指出的那样
perl -ane 'print if 5 <= grep { $_ eq "NA" } @F' test.txt