我有以下两个代码:
nut=`awk "/$1/{getline; print}" ids_lengths.txt`
和
grep -v '#' neco.txt |
grep -v 'seq-name' |
grep -E '(\S+\s+){13}\bAC(.)+CA\b' |
awk '$6 >= 49 { print }' |
awk '$6 <= 180 { print }' |
awk '$4 > 1 { print }' |
awk '$5 < $nut { print }' |
wc -l
我希望我的剧本在这个地方取代“坚果”:
awk '$4 < $nut { print }'
从中返回的数字:
nut=`awk "/$1/{getline; print}" ids_lengths.txt`
但是,上面的代码中的$ 1应该代表来自ids_lengths.txt的列,而不是来自neco.txt的第一列! (类似于我在主代码中使用$ 6和$ 4)。
帮助如何解决这些嵌套的awk肯定会受到赞赏: - )
编辑: 我的输入文件(neco.txt)的行如下所示:
FZWTUY402JKYFZ 2 100.000 3 11 9 4.500 7 0 0 0 . TG TGTGTGTGT
最大的问题是我想过滤那些第五列数小于数字的行,当我用第一列(例如FZWTUY402JKYFZ)搜索时,我从另一个文件(ids_lengths.txt)得到这些行。这就是为什么我在我的草稿中添加“nut”变量: - )
ids_lengths.txt如下所示:
>FZWTUY402JKYFZ
153
>FZWTUY402JXI9S
42
>FZWTUY402JMZO4
158
答案 0 :(得分:4)
您可以将两个grep -v
操作和四个连续awk
操作合并为一个。这为您提供了有用的经济效益,而无需完全重写所有内容:
nut=`awk "/$1/{getline; print}" ids_lengths.txt`
grep -E -v '#|seq-name' neco.txt |
grep -E '(\S+\s+){13}\bAC(.)+CA\b' |
awk -vnut="$nut" '$6 >= 49 && $6 <= 180 && $4 > 1 && $5 < nut { print }' |
wc -l
我不打算让单个awk
脚本确定nut
的值并执行基于值的过滤。它可以完成,但它会不必要地使事情变得复杂 - 除非你能证明整个事情是生产系统性能的瓶颈,在这种情况下你会更努力地工作(尽管在这种情况下我可能会使用Perl;它可以在一个命令中完成所有操作。)
答案 1 :(得分:3)
约:
awk -v select="$1" '$0 ~ select && FNR == NR { getline; nut = $0; } FNR == NR {next} $4 > 1 $5 < nut && $6 >= 49 && $6 <= 180 && ! /#/ && ! /seq-name/ && $NF ~ /^AC.+CA$/ {count++} END {print count}' neco.txt ids_lengths.txt
正则表达式需要调整到AWK理解的东西。我看不出正则表达式与您提供的示例数据的匹配程度。部分解决方案可能是使用字段计数作为条件之一。可能是NF == 13
或NF >= 13
。
以上是为了便于阅读而在多行上分解的脚本:
awk -v select="$1" '
$0 ~ select && FNR == NR {
getline
nut = $0;
}
FNR == NR {next}
$4 > 1
$5 < nut &&
$6 >= 49 &&
$6 <= 180 &&
! /#/ &&
! /seq-name/ &&
$NF ~ /^AC.+CA$/ {
count++
}
END {
print count
}' ids_lengths.txt neco.txt