Скажем, у меня есть следующая структура файлов и каталогов:Как пропустить каталог в awk?
$ tree
.
├── a
├── b
└── dir
└── c
1 directory, 3 files
То есть два файла a
и b
вместе с реж dir
, где другой файл c
стоит.
Я хочу, чтобы обработать все файлы с awk
(GNU Awk 4.1.1
, точно), так что я что-то вроде этого:
$ gawk '{print FILENAME; nextfile}' * */*
a
b
awk: cmd. line:1: warning: command line argument `dir' is a directory: skipped
dir/c
Все это хорошо, но *
также расширяется в каталог dir
и awk
пытается обработать Это.
Так что мне интересно: есть ли какой-либо родной способ awk
может проверить, является ли данный элемент файлом или нет, и если да, пропустите его? То есть, не используя для этого system()
.
Я сделал свою работу, позвонив в BEGINFILE внешний system
:
$ gawk 'BEGINFILE{print FILENAME; if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}} ENDFILE{print FILENAME, FNR}' * */*
a
a 10
a.wk
a.wk 3
b
b 10
dir
dir is a dir, skipping
dir/c
dir/c 10
Отметим также тот факт, что if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}
работает счетчик интуитивно: она должна возвращать 1, если верно, но он возвращает код завершения.
Я прочитал в A.5 Extensions in gawk Not in POSIX awk:
- каталоги в командной строке производит предупреждение и пропускается (см Command-line directories)
А потом связанная страница говорит:
4.11 Справочники на Командная строка
Согласно стандарту POSIX, файлы, названные в командной строке awk , должны быть текстовыми; это фатальная ошибка, если они не являются. Большинство версий awk относятся к каталогу в командной строке как к фатальной ошибке.
По умолчанию gawk выдает предупреждение для каталога по команде , но в противном случае игнорирует его. Это делает его легче использовать Shell символы с AWK программы:
$ gawk -f whizprog.awk * Directories could kill this program
Если какая-либо из --posix или --traditional опции задано, то поглазеть возвращается к обработке каталога в командной строке в виде фатальная ошибка.
См. Extension Sample Readdir, для обработки каталогов как используемых данные из awk-программы.
И на самом деле это так: та же команда, как и раньше с --posix
терпит неудачу:
$ gawk --posix 'BEGINFILE{print FILENAME; if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}} ENDFILE{print FILENAME, NR}' * */*
gawk: cmd. line:1: fatal: cannot open file `dir' for reading (Is a directory)
Я проверил раздел 16.7.6 Reading Directories
, привязанный выше, и они говорят о readdir
:
Расширение readdir добавляет парсер ввода для каталогов. Использование выглядит следующим образом:
@load «READDIR»
Но я не уверен, что ни как назвать его, ни как использовать его из командной строки.
Niiiice! Поэтому 'getline' в каталоге не работает напрямую, но может быть обработан. – fedorqui
RIght. Когда я впервые прочитал ваш вопрос, я подумал, что вы пытаетесь использовать awk для поиска файлов/dirs (извините - короткий охват внимания!), Но при повторном чтении это выглядит так, будто вы просто хотите защитить от того, кто вызывает скрипт с не файлом args - нет ничего плохого в этом, и выше, как вы это делаете. Я обновил свой ответ, чтобы немного поддержать это! –
Да, точно. Это просто для предотвращения предупреждений или даже кодов выхода из-за того, что каталог расширяется в предположительно просто списке файлов. Очень интересный ответ, из которого я узнал довольно много, спасибо:) – fedorqui