Нет необходимости использовать 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
Какой правильный результат.
Конечно, файл
табов
для 3 полей, а Чтобы проверить, соответствует ли файл первому требованию, вы можете использовать следующий сценарий:
#!/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
.
Что касается цитирования и использования переменных, это то, что вы должны улучшить самостоятельно.
Вы можете использовать sed
для удаления строк на месте с параметром -i
:
$ cat foo.txt
bar
baz
lorem
$ sed -i '1d' foo.txt
$ cat foo.txt
baz
lorem
Вы также можете удалить диапазон строк; например sed -i '1,4d' foo.txt
удалит строки 1-4.
РЕДАКТИРОВАТЬ: как Дон указал в комментариях, опция -i
по-прежнему создает копию.
Используя команду tail таким образом:
# tail -n +<lines to skip> filename
например:
tail -n +1000 hugefile.txt > hugefile-wo-the-first-1000-lines.txt
И все .- Для получения дополнительной информации: https://es.wikipedia.org/wiki/ Tail
BTW: Не дайте себя обмануть, если кто-то скажет вам, что это прямо противоположное тому, что вы хотите сделать, я это тестировал:
$ tail -n +3 /tmp/test
3
4
5
$ cat /tmp/test
1
2
3
4
5