Назад | Перейти на главную страницу

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

Я хочу получить последние 10 строк нескольких файлов. Я знаю, что все они заканчиваются на "-access_log". Итак, я попробовал:

 tail -10 *-access_log 

Но это дает мне ошибку, где:

tail -10 file-*

Дает мне результат, которого я ожидал. Я думаю, это скорее связано с BASH, чем с хвостом. Однако такие команды, как:

cat *-access_log

Работают нормально.

Какие-либо предложения?

Я считаю, что вам нужно:

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*'

это дало мне ошибку

хвост: опция используется в недопустимом контексте - 2

тем не мение, хвостохранилище только один файл, например

ssh myserver.com 'tail -2 file-header-file-one'

работает отлично. Глядя на источник tail.c показывает, что хвостик начинается с разбора устаревший options, затем проанализируйте остальные (т.е. параметры еще не обработаны), обычные параметры. Тем не мение, 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 обычная форма, зная, что «устаревший» код принимает только один файл.