xargs и zcat: ошибки молчания

Так и должно быть

awk -F'(,|command:)' '{print $1, $NF}' infile
2018-04-25 00:00:10  show databases

Здесь мы определили разделители полей либо запятой ,, либо строкой command:, затем выводим первое и последнее поля.

0
03.04.2020, 18:11
2 ответа

Несмотря на то, что вы видите сообщение в первой строке, оно записывается не в стандартный вывод, а в стандартную ошибку.

Значит, это должно сработать:

ls files/* | xargs -I {} zcat {} 2>/dev/null | head -n 1

Он отбрасывает стандартный вывод ошибок (отправляет его в /dev/null)

1
28.04.2021, 23:18

Ошибка связана с тем, что zcatполучает отправленный на него сигнал PIPE. Это происходит потому, что во второй раз zcatвыполняется (и все остальные разы после этого, по одному разу для каждого файла, кроме первого ), он пытается записать по каналу в headпосле выхода head(из-за выполнения задачи вывода первой строки ).

Вы можете избежать появления этой конкретной ошибки, прочитав все данные, которые производит zcat. Вы можете сделать это либо

ls files/* | xargs -I {} zcat {} | { head -n 1; cat >/dev/null; }

или

ls files/* | xargs -I {} zcat {} | sed -n 1p

или

ls files/* | xargs -I {} zcat {} | awk 'NR == 1'

Или см. ответ Эдуардо Трапани о том, как просто игнорировать ошибку.

Другой способ сделать это — распаковать только первый файл:

set -- files/*
zcat "$1" | head -n 1

Это не инициирует сигнал PIPEдля zcat, поскольку он выполняется только один раз, а не для каждого отдельного файла в каталоге. Это имело бы дополнительное преимущество, заключающееся в том, что оно справится с любым допустимым именем файла (, например. имена со встроенными символами новой строки ).

1
28.04.2021, 23:18

Теги

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