Подсчет количества вхождений значения столбца в TSV-файле с помощью AWK

В системе GNU:

$ ps --no-header -C sleep -o args | grep -Ec ' 500( |$)'
2
3
24.04.2017, 18:49
3 ответа

Нет необходимости использовать cat для чтения файла. AWK вполне способен его прочитать.

Основной оператор c[$3]++ должен получать количество строк каждого типа.
Затем, в конце, просто напечатайте (в виде значений, разделенных табуляцией) все счетчики:

#!/bin/bash

awk -F '\t' '   {c[$3]++}
                 END{
                     for (i in c) printf("%s\t%s\n",i,c[i])
                 }' dataset.csv 

Добавлено

Учитывая комментарий из OP, который:

Я получаю некоторые проблемы для столбцов, которые имеют кавычки, такие как , что не означает, что вас не стоит помнить, подумайте о людях, которым нужно знать, что они должны знать, поэтому вам нужно показать.... В этом случае синтаксический анализ \t завершится ошибкой.

Мне нужно просмотреть ответ. Я создал этот файл:

$ cat dataset.csv 
1233    that doesn\'t mean that you\'re not worth remembering think of the people who need to know they need to know so you need to show...    CLASS_0
1234    here    CLASS_A
1235    goes the values CLASS_B
1236    "that need counting"    CLASS_B
1237    "\like \this"   CLASS_B
1238    \or \this       CLASS_C
1239    including spaces        CLASS_B
1240    but not tabs    CLASS_A
1241    which could not work    CLASS_B
1242    finally CLASS_C
1243    this is CLASS_A
1244    over    CLASS_B
1245    988     CLASS_C

Этот файл при использовании со сценарием дает правильный результат:

$ ./script
CLASS_A 3
CLASS_B 6
CLASS_C 3
CLASS_0 1

Какой правильный результат.

Конечно, файл

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

Чтобы проверить, соответствует ли файл первому требованию, вы можете использовать следующий сценарий:

#!/bin/bash

filetoread="$2"

<"$filetoread" tr -dc '\t\n' |
    awk '(length!=2){printf("Error in line: %s, has %s tabs\n",NR,length)}'

awk -F '\t' '(NF!=3){printf("Error in line: %s, has %s fields\n",NR,NF)}' "$filetoread"

Который проверяет наличие ровно двух вкладок в строке и
Что количество полей (как видно из awk) на самом деле три.

Добавление пары тестовых строк:

… …
1239    including spaces        CLASS_B
1       but not     tabs    CLASS_A
2       but not \ttabs  CLASS_A
1240    but not tabs    CLASS_A
… …

И запуск сценария выше:

$ ./script 3 dataset.csv
Error in line: 8, has 4 tabs
Error in line: 8, has 5 fields

обнаруживает строку с идентификатором 1, которая имеет четыре вкладки (две добавлены) и не обманывается строкой с идентификатором 2 с \t.

Что касается цитирования и использования переменных, это то, что вы должны улучшить самостоятельно.

4
27.01.2020, 21:10

Надеюсь, я правильно понял, что столбец 3 может содержать либо "CLASS_A", либо "CLASS_B", либо "CLASS_C"?

Тогда

awk -F'\t'  '
 { seen[$3]++ ;}
 END { for (i in seen) {
         printf "%s : %s\n",i,seen[i]
       }
      } 
 ' /dataset.csv

Должен ли сработать трюк?

Обратите внимание, что «for (i in visible)» не гарантирует, что они читаются в «правильном порядке», но вы можете добавить | sort (после всего awk), чтобы отсортировать их, или использовать более сложные трюки (внутри awk).

Если вам нужно также пройти через первую строку (например, если она содержит заголовки), добавьте перед первой строкой в ​​awk-скрипте:

( NR==1 ) { next ;}

или измените первую строку следующим образом:

( NR > 1 ) { seen[$3]++ ;}
3
27.01.2020, 21:10

Что-то вроде этого может выполнить эту работу:

awk -F'\t' ' 
            $3=="CLASS_A" {a+=1} 
            $3=="CLASS_B" {b+=1} 
            $3=="CLASS_C" {c+=1} 
            END {
                printf "%s %d\n%s %d\n%s %d", CLASS_A,a,CLASS_B,b,CLASS_C,c
            }' /dataset.csv
3
27.01.2020, 21:10

Теги

Похожие вопросы