Может ли awk пропустить файлы, которые не существуют, без расы? - PullRequest
5 голосов
/ 20 октября 2008

Есть ли способ заставить awk (gawk) игнорировать или пропускать отсутствующие файлы? То есть файлы, переданные в командной строке, которые больше не существуют в файловой системе (например, быстро появляющиеся / исчезающие файлы в /proc/[1-9]*).

По умолчанию отсутствующий файл является фатальной ошибкой: - (

Я бы хотел сделать что-то подобное:

BEGIN { MISSING_FILES_ARE_FATAL = 0 }  # <- Wishful thinking!
      { count++ }
END   { print count }

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

Ответы [ 6 ]

2 голосов
/ 10 сентября 2012

GAWK 4 имеет BEGINFILE, в котором вы можете проверить на ERRNO и сделать nextfile, если ERRNO не пусто (указывая, что файл не может быть открыт).

1 голос
/ 07 января 2009

Мне кажется, что функция "MISSING_FILES_ARE_FATAL = 0" будет частью следующего выпуска gawk. См. Файл ChangeLog текущего исходного кода gawk-stable:

--- snip ---

Пт, 22 августа 14:43:49 2008 Арнольд Д. Роббинс

* io.c (nextfile): Users Strong In The Ways Of The Source can use
non-existant files on the command line without it being a fatal error.

--- snip ---

http://cvs.savannah.gnu.org/viewvc/gawk-stable/ChangeLog?revision=1.87&root=gawk&view=markup

Hermann

1 голос
/ 20 октября 2008

Ну, вы можете проверить с помощью системного вызова содержимое ARGV, а затем обработать их с помощью getline.

 if (system("test -r " ARGV[1]) == 0)
   while ( (getline aline < ARGV[1]) >0 )
     # process ARGV[1] via `aline` instead of $0

...

Затем обработайте ARGV [2] и т. Д. НТН

1 голос
/ 20 октября 2008

Даже прилипая к вашему awk-скрипту perl или shell-оболочкой, я думаю, что все еще будет условие гонки. Например, используя отличный фрагмент кода ADEpt:

[ -r "$filename" ] && awk -f ... $filename

ничто не мешает процессу уйти между -r и временем, когда awk пытается открыть файл ...

Единственный ответ, который я могу придумать, - это использовать LD_PRELOAD для замены системного вызова open на awk, так что если файл отсутствует, вместо него открывается дескриптор файла чтения в / dev / null.

Это может сработать ...

0 голосов
/ 22 октября 2008

Ой, прости. Не обращайте внимания на мой предыдущий ответ. Вот еще одно предложение:

cat /proc/[1-9]* 2>/dev/null | awk ....

Cat сожрет все файлы, как отсутствующие, так и существующие, ошибка cat будет сброшена в забвение (отсутствующий файл является нефатальной ошибкой для cat), и awk сможет обработать результат.

0 голосов
/ 20 октября 2008

В лучших традициях я отвечу на ваш вопрос на awk с помощью программы Perl.

#!/usr/bin/perl -w

for my $file (@ARGV) {
    open my $fh, $file or next;
    while(<$fh>) {
        ...do your thing here...
    }
}

(Это не awk, но это единственное решение без условий гонки.)

...