Portanto, abrir um arquivo cat
e usá grep
-lo para obter linhas correspondentes só me leva a um ponto em que estou trabalhando com o conjunto de logs específico com o qual estou lidando. Ele precisa de uma maneira de corresponder linhas a um padrão, mas apenas para retornar a parte da linha após a correspondência. A parte antes e depois da partida variará consistentemente. Eu brinquei com o uso de sed
ou awk
, mas não consegui descobrir como filtrar a linha para excluir a parte antes da partida ou apenas retornar a parte após a partida, ou funcionará. Este é um exemplo de uma linha que eu preciso filtrar:
2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.amd64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }
A parte que eu preciso é tudo depois de "parado".
O pano de fundo por trás disso é que eu posso descobrir com que frequência algo pára:
cat messages | grep stalled | wc -l
O que eu preciso fazer é descobrir quantas vezes um determinado nó parou (indicado pela parte antes de cada dois pontos depois de "parado". Se eu apenas esperar por isso (ou seja, 20 :), ele pode retornar linhas que apresentam falhas suaves, mas sem interrupções, o que não me ajuda.Preciso filtrar apenas a parte paralisada para que eu possa receber um nó específico daqueles que pararam.
Para todos os efeitos, este é um sistema freebsd com utilitários padrão do GNU, mas não consigo instalar nada extra para ajudar.
fonte
sed
solução e não trate especialmente os espaços em branco.Respostas:
A ferramenta canônica para isso seria
sed
.Explicação detalhada:
-n
significa não imprimir nada por padrão.-e
é seguido por um comando sed.s
é o comando de substituição de padrão.^.*stalled:
corresponde ao padrão que você está procurando, além de qualquer texto anterior (.*
ou seja, qualquer texto, com uma inicial^
para dizer que a correspondência começa no início da linha). Observe que sestalled:
ocorrer várias vezes na linha, isso corresponderá à última ocorrência.stalled:
, é substituída pela sequência vazia (ou seja, excluída).p
meio final para imprimir a linha transformada.Se você deseja reter a parte correspondente, use uma referência posterior:
\1
na peça de substituição designa o que está dentro de um grupo\(…\)
no padrão. Aqui, você pode escreverstalled:
novamente na peça de substituição; esse recurso é útil quando o padrão que você procura é mais geral do que uma sequência simples.Às vezes, você deseja remover a parte da linha após a partida. Você pode incluí-lo na correspondência incluindo
.*$
no final do padrão (qualquer texto.*
seguido pelo final da linha$
). A menos que você coloque essa parte em um grupo que você referencia no texto de substituição, o final da linha não estará na saída.Como uma ilustração adicional de grupos e referências anteriores, esse comando troca a parte antes da partida e a parte após a partida.
fonte
sed … <messages
, já que deseja processar dados de um arquivo. A agir em dados produzidos por outro comando, você pode usar um tubo:somecommand | sed …
.sed 's/^.*stalled//'
pois-r
é específico para Linux e não funciona em outros sistemas, como o macOS, e aqui você não está obtendo nenhum benefício.A outra ferramenta canônica que você já usa
grep
::Por exemplo:
Tem o mesmo resultado que a segunda opção de Gilles:
A
-o
flag retorna a--only-matching
parte da expressão, portanto, não a linha inteira que é, é claro, normalmente feita pelo grep.Para remover o "parado:" da saída, podemos usar uma terceira ferramenta canônica, corte:
O
cut
comando usa delimitador:
e imprime o campo 2 até o final. É uma questão de preferência, é claro, mas acut
sintaxe é muito fácil de lembrar.fonte
-o
opção! Eu gostaria de salientar quegrep
não reconhece o\n
como uma nova linha; portanto, seu primeiro exemplo corresponde apenas ao primeiron
caractere. Por exemplo,echo "Hello Anne" | grep -o 'A[^\n]*'
retorna a stringA
. No entanto,echo "Hello Anne" | grep -o 'A.*'
retorna o esperadoAnne
, pois.
corresponde a qualquer caractere, exceto a nova linha.cut
delimitador-d':'
são removidas por @poige. Acho mais fácil lembrar com aspas, por exemplo, com-d' '
ou-d';'
.-f 2
também. Sério, por que não?;
e vírgula, em vez de dois pontos:
, será interpretado de maneira diferente, se não for citado. Claro que é um comportamento lógico, mas ainda gosto de confiar na memória muscular. Não gosto de citar o delimitador uma vez, mas não na outra. Apenas preferência pessoal, como eu disse antes: mais fácil de lembrar..*
é necessário, funcionou bem para mim:cat filename | grep 'Return only this line xyz text' | grep -o 'xyz.*'
retornosxyz text
Eu costumava
ifconfig | grep eth0 | cut -f3- -d:
levar issoe torná-lo assim
fonte
cat /sys/class/net/*/address
, sem necessidade de análise.No entanto, outra ferramenta canônica que você considerou
awk
poderia ser usada com a seguinte linha:Explicação detalhada:
-F
define um separador para a linha, ou seja, "parado". Tudo antes do separador é tratado$1
e tudo depois com$2
./reg-ex/
Procura a expressão regular correspondente, neste caso "paralisada".{print $<n>}
- imprime n coluna. Como seu separador é definido como paralisado, tudo depois de paralisado é considerado a segunda coluna.fonte