Comando Linux para procurar arquivos usando pipes

0

Problema: preciso encontrar os 5 serviços que produziram a maioria das mensagens de registro nos arquivos /var/log/syslog e /var/log/syslog.1 .

  • tr - para remover números de processo, para que todos os processos pareçam iguais.

  • cut - para mostrar apenas o nome do processo.

Além disso, acho que preciso usar os comandos uniq , sort e head .

    
por RSICK 14.03.2018 / 10:16

2 respostas

2

O nome do serviço está disponível na coluna cinco no arquivo de log syslog (como encontrado em uma máquina Ubuntu com configuração syslog padrão). Geralmente é listado como servicename[pid]: , por exemplo CRON[1233]: ou ntpd[9283]: etc.

Para obter o quinto campo:

awk '{ print $5 }' /var/log/syslog

Para excluir tudo desse campo, do [ onwards:

awk '{ sub("[[].*", "", $5); print $5 }' /var/log/syslog

Agora você terá uma lista como

dhclient
dhclient
dhclient
CRON
ntpd
CRON
CRON
ntpd

Agora você só precisa classificá-los e contá-los e manter os melhores:

awk '{ sub("[[].*", "", $5); print $5 }' /var/log/syslog |
sort | uniq -c | sort -rn | head -n 5

Isso pode produzir algo como

 27 dhclient
 23 CRON
 13 ntpd

(apenas três serviços nesta máquina em particular).

Para remover os números, filtre por awk '{ print $2 }' .

Você também pode usar tr e cut , mas essas ferramentas são um pouco "simples" demais para esse trabalho IMHO. cut , em particular, precisa saber exatamente quantos caracteres delimitadores serão cortados, portanto, se uma coluna for delimitada por mais de um caractere de espaço, cut precisará levar isso em conta.

    
por 14.03.2018 / 10:55
1

tr transliterar caracteres indiscriminadamente, não é realmente apropriado aqui tr -d 0-9 removeria todos os dígitos decimais, inclusive os nomes de serviço. Pode ser útil, entretanto, espremer seqüências de delimitadores em um, de modo que cut possa ser usado.

O que você precisa é localizar a coluna que contém o nome do serviço e extrair o nome do serviço a partir dele.

Qual coluna ela irá depender de como o syslog foi configurado, em particular quando se trata da formatação do timestamp.

Você pode ver coisas como:

2018-03-13T07:17:01.506581-07:00 host CRON[26456]: (root) CMD (...)

Onde o nome do serviço está na terceira coluna ou:

Mar 14 00:35:01 host CRON[19234]: (root) CMD (...)

Onde está na quinta coluna.

Nesse último formato, pode haver 1 ou 2 espaços entre as colunas de mês e dia (é onde você usa tr -s ' ' se quiser usar cut nele). Observe também que não é garantido que a parte [pid] esteja lá (como para logs de kernel ou logs recebidos pela rede (esses últimos podem nem ter uma coluna "service")).

Um método que funcionaria para esses dois formatos diferentes, com o GNU grep ou compatível com o suporte a PCRE, seria:

grep -Po '^.{7}\S+ \S+ \K[^\s:[]+' /var/log/syslog |
  sort |
  uniq -c |
  sort -rn |
  head -n 5

Isso é ignorar os primeiros 7 caracteres e todos os sem espaçamento após esse (que abrangerá o registro de data e hora dos dois formatos) e uma coluna extra ( \S+ entre dois espaços: o nome do host) e, em seguida, corresponder a sequência de caracteres diferente de espaçamento, dois pontos e ] depois disso ( \K marcando o início da parte correspondida).

Uma abordagem baseada em regex, aqui usando os mais semelhantes a perl ricos em recursos, oferece muito mais flexibilidade. O mesmo expresso com cut seria:

</var/log/syslog cut -c 8- |
  cut -d ' ' -f3 |
  cut -d : -f 1 |
  cut -d '[' -f 1 |
  sort |
  uniq -c |
  sort -rn |
  head -n 5
    
por 14.03.2018 / 10:51