Хвост и символы подстановки
Я хочу получить последние 10 строк нескольких файлов. Я знаю, что все они заканчиваются на "-access_log". Итак, я попробовал:
tail -10 *-access_log
Но это дает мне ошибку, где как:
tail -10 file-*
Дает мне результат, который я ожидаю. Я думаю, что это скорее связано с BASH, чем с tail. Однако такие команды, как:
cat *-access_log
Отлично работает
Какие-либо предложения?
2 ответа
Я полагаю, вы бы хотели:
tail -n 10 *-access.log
Что касается того, почему:
Я не думаю, что это имеет какое-либо отношение к глобализации:
tail -10 foo-access.log arf-access.log
tail: option used in invalid context -- 1
Я думаю, что так получилось, что ваш глобус расширяется до одного файла. Вероятно, это как-то связано с анализом некоторых архаичных опций, которые мне лень читать, но если вы действительно хотите это знать, поищите tail.c
в источнике coreutils и рассекаем следующую функцию:
parse_obsolete_option (int argc, char * const *argv, uintmax_t *n_units)
Хотя немного стар, вопрос все еще актуален. Я встретил похожую проблему
ssh myserver.com 'tail -2 file-header*'
это дало мне ошибку
tail: опция используется в недопустимом контексте - 2
однако, следя только за одним файлом, как
ssh myserver.com 'tail -2 file-header-file-one'
работает отлично. Просмотр исходного файла tail.c показывает, что tail начинается с анализа устаревших параметров, а затем анализирует остальные (т. Е. Параметры еще не обработаны) обычные параметры. Тем не мение, parse_obsolete_option()
ожидает "устаревшего" использования, только с одним файлом в качестве аргумента.
Поэтому, когда вы предоставляете больше файлов, функция немедленно возвращается и позволяет обычному парсеру подавиться -2
(ожидается -n 2
).
/* With the obsolete form, there is one option string and at most
one file argument. Watch out for "-" and "--", though. */
if (! (argc == 2
|| (argc == 3 && ! (argv[2][0] == '-' && argv[2][1]))
|| (3 <= argc && argc <= 4 && STREQ (argv[2], "--"))))
return false;
В заключение, лучше всегда использовать -n
обычная форма, зная, что "устаревший" код принимает только один файл.
На самом деле такое поведение хвоста GNU (-COUNT принимает только один файл) задокументировано. https://www.gnu.org/software/coreutils/manual/html_node/tail-invocation.html
Для совместимости tail также поддерживает устаревшее использование 'tail -[num][bcl][f] [file]' ", которое распознается, только если оно не конфликтует с использованием, описанным выше. Эта устаревшая форма использует только один параметр и не более одного файла.
Его также можно найти на установленной информационной странице coreutils.
shell> info tail
Обратите внимание, что, наоборот, "head -COUNT" поддерживает несколько файлов.