我有一个制表符分隔文件:
scaffold_0 102 1 4 0 1 1 1 2 1 2 1 3
scaffold_0 103 1 4 0 2 1 1 2 1 2 1 3
scaffold_0 104 2 4 0 2 3 5 2 1 2 7 3
scaffold_0 105 1 4 0 2 1 1 2 1 2 1 3
scaffold_0 106 1 4 0 2 1 1 2 1 2 1 3
scaffold_0 107 2 3 3 2 5 1 2 1 2 2 4
scaffold_0 108 1 4 0 2 1 1 2 1 2 2 5
scaffold_0 109 1 4 0 2 1 1 2 1 2 2 5
scaffold_0 110 1 3 0 2 1 1 2 1 2 2 5
scaffold_0 111 1 3 0 2 1 1 1 1 2 2 5
,并且需要抓住9或更多列中显示等于或大于2的行。 这样就可以了:
scaffold_0 104 2 4 0 2 3 5 2 1 2 7 3
scaffold_0 107 2 3 3 2 5 1 2 1 2 2 4
另一种放置方式是,我必须删除每行大于2的0和1s计数的行。
我尝试过:
grep '[2-9]\t{9,}'
它不起作用,即使这样做也不会抓住10、11、101等。
(抓住2、12、22等应该不是问题)
答案 0 :(得分:3)
$ awk '{c=0; for (i=2;i<=NF;i++) c+=($i>=2)} c>8' file
scaffold_0 104 2 4 0 2 3 5 2 1 2 7 3
scaffold_0 107 2 3 3 2 5 1 2 1 2 2 4
它可以在任何UNIX机器上的任何外壳中工作,并且运行速度比当前接受的答案快几个数量级。
答案 1 :(得分:1)
while IFS= read -r line; do
count=$(
<<<"$line" cut -f2- |
tr '\t' '\n' |
grep -x '0\|1' |
wc -l
)
if (( count <= 2 )); then
echo "$line"
fi
done <file
对于每一行,从文件的第二行开始获取所有字段,然后用制表符代替换行符,仅过滤零或一的行,然后计算行数。如果计数小于或等于2,则打印该行。
grep -v -x '0\|1' | wc -l
和(( count > 9 ))
。tutorialspoint上的实时示例。
答案 2 :(得分:1)
使用numgrep
:
while read x ; do
numgrep -l '/2../' <<< "$x" | { [ $(wc -l) -ge 9 ] && echo "$x" ; } ;
done < file
输出:
scaffold_0 104 2 4 0 2 3 5 2 1 2 7 3
scaffold_0 107 2 3 3 2 5 1 2 1 2 2 4
请注意:numgrep
和此代码将可同时使用负数和小数。