Хвост и символы подстановки

Я хочу получить последние 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" поддерживает несколько файлов.

Другие вопросы по тегам