подсчитать количество строк с определенным количеством столбцов

подсчитать количество строк с определенным количеством столбцов

У меня есть несколько файлов со следующим содержимым:

GGHTERR_01218   GGHTERR_02418   GGHTERR_01991
GGHTERR_02211   GGHTERR_02297   GGHTERR_02379
GGHTERR_02294   GGHTERR_02455   GGHTERR_02374
GGHTERR_00532   GGHTERR_00534
GGHTERR_00533   GGHTERR_00535
GGHTERR_00776   GGHTERR_00779
GGHTERR_01220   GGHTERR_01620
GGHTERR_01760   GGHTERR_01761
GGHTERR_01774   GGHTERR_02404
GGHTERR_01889   GGHTERR_01890
GGHTERR_02081   GGHTERR_02287
GGHTERR_02152   GGHTERR_02153
GGHTERR_02260   GGHTERR_02321
GGHTERR_02295   GGHTERR_02375
GGHTERR_02419   GGHTERR_02437
GGHTERR_02420   GGHTERR_02438
GGHTERR_02430   GGHTERR_02448
GGHTERR_00001
GGHTERR_00002
GGHTERR_00003
GGHTERR_00004
GGHTERR_00005
GGHTERR_00006
GGHTERR_00007

Я хотел бы узнать, есть ли простой способ подсчитать количество строк, имеющих 3 столбца, 2 столбца и 1 столбец.

Итак, вывод должен выглядеть так:

3 columns: 3
2 columns: 14
1 colums: 7

решение1

Awk идеально подходит для этого. Он разделит строки по пробелам (по умолчанию; измените с помощью параметра -F), а внутренняя переменная NF(число полей) содержит число полей в строке. Так что просто пройдитесь по файлу, сохраняя NFдля каждой строки:

awk '{ 
        nums[NF]++
     }
     END{
        for(num in nums){
            printf "%d columns: %d\n", num, nums[num]
        }
     }' file

Код выше просто сохраняет количество полей ( NF) в ассоциативном массиве nums, ключи которого — это количество полей, а значения — это количество раз, когда это количество столбцов было найдено в файле. В конце мы просто проходим по массиву и печатаем. Запуск вышеприведенного кода на вашем примере приводит к:

$ awk '{ nums[NF]++}END{for(num in nums){printf "%d columns: %d\n", num, nums[num]}}' file
1 columns: 7
2 columns: 14
3 columns: 3

Один (небольшой) недостаток этого подхода заключается в том, что вам нужно будет хранить запись для каждой строки файла в памяти. Это не будет проблемой, если только ваш файл не совсем гигантский или у вас не очень мало доступной памяти, но если это так, вы можете обойти это, просто выведя количество полей на строку и затем подсчитав:

$ awk '{ print NF}' file | sort | uniq -c
      7 1
     14 2
      3 3

Или, чтобы получить тот же результат:

$ awk '{ print NF}' file | sort | uniq -c | while read num fields; do printf "%d columns: %d\n" "$num" "$fields"; done
7 columns: 1
14 columns: 2
3 columns: 3

решение2

Не awkрешение, возможно немного громоздкое:

$ a=$(grep '^[GHTER_0-9]\+[[:space:]]\+[GHTER_0-9]\+[[:space:]]\+[GHTER_0-9]\+$' file | wc -l)
$ b=$(grep '^[GHTER_0-9]\+[[:space:]]\+[GHTER_0-9]\+$' file | wc -l)
$ c=$(grep '^[GHTER_0-9]\+$' file | wc -l)
$ printf "3 columns %s\n2 columns %s\n1 column %s\n" $a $b $c
3 columns 3
2 columns 14
1 columns 7

Связанный контент