删除每列中包含 NA 的行

use*_*373 8 awk perl text-processing bioinformatics

我有一个制表符分隔的文件,如下所示:

gene    v1  v2  v3  v4
g1  NA  NA  NA  NA
g2  NA  NA  2   3
g3  NA  NA  NA  NA
g4  1   2   3   2
Run Code Online (Sandbox Code Playgroud)

每行中的字段数是固定且相同的。我想从上面的文件中删除那些行,其中从第 2 列到最后一列的每一行的所有字段都是 NA。然后输出应如下所示:

gene    v1  v2  v3  v4
g2  NA  NA  2   3
g4  1   2   3   2 
Run Code Online (Sandbox Code Playgroud)

Fre*_*ddy 16

awk

awk '{ for (i=2;i<=NF;i++) if ($i!="NA"){ print; break } }' file
Run Code Online (Sandbox Code Playgroud)

循环遍历从第二个字段开始的字段,如果NA找到不包含的字段,则打印该行。然后打破循环。


eik*_*ike 10

使用 GNU sed

sed -e '/g[0-9]\+\(\s*NA\s*\)\+$/d' filename
Run Code Online (Sandbox Code Playgroud)

简短说明:

g[0-9]\+\(\s*NA\s*\)\+$是一个正则表达式匹配,g后跟至少一个数字,然后是任意数量的NAs,在行尾之间有可选的空格。

sed -e '/<regex>/d' 删除所有匹配的行 <regex>

具有相同含义的更标准的正则表达式是:

sed -Ee '/g[0-9]+([[:space:]]*NA[[:space:]]*)+$/d' filename
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`\+` 和`\s` 是非标准的正则表达式,在大多数`sed` 版本中将匹配简单的`+` 或`s`。使用 `\{1,\}` 代替 `\+` 和 `[[:space:]]` 代替 `\s` 以获得可移植的代码。 (4认同)

ste*_*ver 9

随着all从Perl的名单::的Util模块:

$ perl -MList::Util=all -alne 'shift @F; print unless all { $_ eq "NA" } @F' file
gene  v1  v2  v3  v4
g2    NA  NA  2   3
g4    1   2   3   2
Run Code Online (Sandbox Code Playgroud)


Jim*_* L. 9

grep

egrep -v -x 'g[0-9]+([[:blank:]]+NA)*[[:blank:]]*' filename
Run Code Online (Sandbox Code Playgroud)

这会导致 grep显示 ( -v) 整行 ( -x) 匹配的行:

  • 第一列中的小写 g,后跟一个或多个数字
  • 任意数量的空格实例,后跟 NA
  • 可选的尾随空格