
Я немного поискал site:
в Google по Server Fault, Super User и Stack Overflow. Я также проверил результаты, не относящиеся к сайту, и не увидел такого вопроса, так что вот...
Я заметилэтот вопрос, связанный с grep и awkкоторый обладает некоторыми большими знаниями, но я не чувствую, что проблема квалификации текста была решена. Этот вопрос также расширяет область действия до любой платформы и любой программы.
У меня есть логи squid или apache, основанные на комбинированном формате NCSA. Когда я говорю «основанный», я имею в виду, что первые n столбцов в файле соответствуют комбинированным стандартам NCSA, может быть больше столбцов с пользовательскими вещами.
Вот пример строки из объединенного журнала Squid:
1.1.1.1 - - [11/Dec/2010:03:41:46 -0500] "GET http://yourdomain.com:8080/en/some-page.html HTTP/1.1" 200 2142 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; C) AppleWebKit/532.4 (KHTML, like Gecko)" TCP_MEM_HIT:NONE
Я хотел бы иметь возможность анализировать
n
журналы и выводить определенные столбцы для сортировки, подсчета, поиска уникальных значений и т. д.
Основная проблема, которая делает этот вопрос немного сложным, а также то, почему я считаю, что этот вопрос еще не был задан и на него не ответили, заключается в следующем:головоломка квалификации текста.
Когда я заметилasqlиз вопроса grep/awk я был очень взволнован, но потом понял, что он не поддерживает combined из коробки, что-то, что я думаю, я рассмотрю в плане расширения.
С нетерпением жду ответов и новых знаний! Ответы не обязательно должны ограничиваться платформой или программой/языком. В контексте этого вопроса, платформы, которые я использую чаще всего, это Linux или OSX.
Ваше здоровье
решение1
Использует Perl, протестировано на версии 5.10.0, собранной для darwin-thread-multi-2level (OSX)
Чтобы распечатать столбец UserAgent:
perl -n -e '/^([^ ]+) ([^ ]+) ([^ ]+) (\[[^\]]+\]) "(.*) (.*) (.*)" ([0-9\-]+) ([0-9\-]+) "(.*)" "(.*)"/; print "$11\n"' -- test.log
- вариант
-n
, пока каждая строка вtest.log
- вариант
-e
однострочной программы
Я украл и подправил перл, который я искал в Googleиз книги рецептов PHP. Я удалил $
из конца re для поддержки пользовательских форматов на основе NCSA combined. Шаблон можно легко расширить, чтобы предоставить больше групп.
Группы регулярных выражений ()
в конечном итоге становятся локальными $1
переменными$n
Быстрый и грязный, очень простой в расширении и написании сценариев.
Некоторые примеры конвейеризации вывода:
| sort | uniq
уникальные значения столбцов| sort | uniq | wc -l
уникальное количество столбцов
Критика и улучшения приветствуются
решение2
Хотя это не решает напрямую квалификацию текста, один фактор, который можно использовать в комбинированном формате, заключается в том, что оставшиеся столбцы, разделенные пробелами, находятся последовательно в одном и том же столбце. Поэтому вы можете обойти эту проблему, используя цикл с printf и NF (количество столбцов)
Согласно awk, $0 — это вся входная строка, $1 — первый столбец, $2 — второй, а $NF — последний.
Таким образом, для стандартного NCSA объединенный пользовательский агент - это столбцы от $13 до $NF.
Мне нужно было удалить первый столбец и поменять его местами с последним столбцом измененного формата журнала (проксированный IP был добавлен в последний столбец).
Итак, должен быть возвращен столбец $NF, за которым следует второй столбец ($2), а затем оставшиеся столбцы до NF - 1.
Мне удалось сделать это с помощью следующего:
awk '{ printf "%s ", $NF; for (i=2; i<=NF-1; i++) printf "%s ", $i; printf "\n";}' < /var/log/nginx/access.log