Мне нужно опросить заголовок CSV-файла, и если столбец существует, продолжить работу со строками данных. Контекст — это когда данные содержат столбцы в зависимости от того, когда и что их выдало.
Надеюсь на «чистое» решение Awk, позволяющее сохранить бизнес-логику на общем языке, но если это невозможно, интересуют подходы, которые выборочно доставляют файлы с заголовком, соответствующим скрипту Awk.
Всегда можно использовать последнюю версию Gawk.
Отредактируйте, чтобы добавить псевдокод:
если столбец в заголовке (NR==1): то продолжайте обработку оставшейся части файла, в противном случае остановите обработку файла
решение1
для вывода списка файлов:
пытаться
awk 'FNR == 1 && $4 == "whatever" { print FILENAME ;}' file1 ... filen |
который выберет все файлы, содержащие что-либо в четвертом столбце.
Если у вас смешное имя, просто добавьте кавычки.
awk 'FNR == 1 && $4 == "whatever" { printf "\"s\"\n", FILENAME ;}' file1 ... filen |
для обработки одного файла
awk 'NR == 1 && $4 != "whatever" { exit ;} other patterns { other action;}' file
для обработки многих файлов
awk 'NR == 1 && $4 != "whatever" { nextfile ;} other patterns { other action;}' file1 ... filen
что можно было бы прочитать как
- ЕСЛИ (условие не выполнено)
NR == 1 && $4 != "whatever"
- ТОГДА пропустите этот файл
{ nextfile ;}
- ИНАЧЕ продолжить
other patterns { other action;}
решение2
Предположим, что файл простой, разделен запятыми, где каждая запятая является разделителем (некоторые CSV-файлы могут содержать запятые в кавычках, которые не следует рассматривать как разделители полей). Следующий код выводит каждую строку, кроме заголовка, если столбец в заголовке равен «SOMESTRING»:
awk -F, '
FNR==1 {
for (i=1; i<=NF; i++)
if ($i == "SOMESTRING")
next
nextfile
}
1
' file1 file2 file3 file4
При необходимости сравнение строк можно заменить проверкой подстроки или операцией сопоставления регулярного выражения.
nextfile не является частью POSIX AWK, но широко распространен; он доступен по крайней мере в gawk, nawk (используется в системах *BSD), mawk и busybox.
решение3
awk 'FNR==1 && ! /whatever/ { nextfile } ; ...remainder of awk script here...' list_of_files_to_process
Это должно привести к переходу к следующему обрабатываемому файлу, если только «whatever» не находится в строке 1.
Я не помню, nextfile
является ли это расширением GNU awk или оно доступно также в других awk. mawk
На странице руководства об этом не упоминается, но оно упоминается на странице руководства для original-awk
. Если это для вас важно, проверьте это, прежде чем полагаться на эту функцию.
Если вы используете GNU awk, вы можете поместить эту проверку в BEGINFILE
такой блок:
BEGINFILE { FNR==1 && ! /whatever/ { nextfile } } ;
... remainder of awk script here ...