Вывести строки, содержащие заданное число, за которым следует табуляция не менее n раз - PullRequest
0 голосов
/ 08 октября 2018

У меня есть файл с разделителями табуляции:

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

, и мне нужно захватить строки, для которых числа, равные или превышающие 2, отображаются в 9 или более столбцах.Итак, у меня есть:

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

Другой способ поместить это то, что мне нужно удалить строки, для которых число 0 и 1 больше 2 на строку.

Я пытался:

grep '[2-9]\t{9,}'

Это не работает, и даже если бы он это сделал, он не взял бы 10, 11, 101 и т. Д.

(захват 2,12, 22 и т. Д. Не должно быть проблемой)

Ответы [ 3 ]

0 голосов
/ 08 октября 2018

Использование 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 и этот код будут работать правильнос отрицательными и десятичными числами.

0 голосов
/ 08 октября 2018
$ 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 и работать на несколько порядков быстрее, чем принятый в настоящее время ответ.

0 голосов
/ 08 октября 2018
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, выведите строку.

  1. Я пошел с нулями и единицами, потому что я думаю, что это будет быстрее (меньше строк для wc -l для подсчета, меньше строк для grepпечатать), но вы можете grep -v -x '0\|1' | wc -l и (( count > 9 )) так же легко.
  2. У меня такое ощущение, что кто-то опубликует лучшее решение на awk, но я не знаю, как хорошо написать awk, чтобы написать такое самому.
  3. Это не будет работать с отрицательными числами.

Живой пример на tutorialspoint .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...