
Estou tendo um arquivo de texto do seguinte tipo,
a b c d
-- -- -- --
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
Eu tentei usar grep para "problema", mas apenas a primeira linha de 'd' foi impressa. A saída que obtive é:
1 ok device issue Some Action which
No entanto, quero a saída completa em d. Quando tentei salvar o arquivo em csv, ele mostrou a segunda linha da coluna d como uma nova linha.
Editar:
A saída é obtida de vários dispositivos armazenados em uma variável da qual estou procurando aquele que está com problemas.
Responder1
Você precisa de um grep multilinha aqui. Para o qual precisaremos da -P
opção habilitada para PCRE. Como grep produzirá registros delimitados por nulos no -z
modo slurp, nós os removemos por meio do comando tr.
$ < file grep -Pzo '.*\S.*issue.*\n(?:\h+.*\n)+' | tr -d '\0'
Responder2
grep
está agindo como deveria no modo padrão. Da sua man
página:
...grep procura PATTERNS em cada FILE. PATTERNS é um ou mais padrões separados por caracteres de nova linha, e grep imprime cada linha que corresponde a um padrão...
Então, é suposto aparecerlinhasno texto correspondente a regex
. As linhas são demarcadas pelo newline
código de controle, que explica o comportamento que você está vendo. Além de usar a -z
opção mencionada nas respostas. Supondo que "problema" seja o regex que você deseja corresponder (substitua por 'Device Degraded'
ou '\sDegraded'
ou '\sError'
se é isso que você realmente deseja corresponder); e que a coluna "Ação Corretiva" é gerada por máquina e consistente, ou seja, sempre abrangendo 4 linhas, você também pode simplesmente executar grep -A 3 '\sissue' > issues
para salvarapenas as linhas que você está interessadoem um arquivo. Você deve ser capaz de gerar uma saída semelhante a:
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
--
10 ok device issue Some Action which
has to be taken which
is split into may lines
under d.
--
211 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
verifique a página de manual do grep para saber mais sobre o que essas opções fazem.
Responder3
Supondo que um "registro" no arquivo de entrada seja exatamente aquele fornecido pelo OP:
$ sed '/issue/!d; :a; n; /^[0-9]\{1,\} /d; $!ba' file
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
$
Responder4
Isso pode ser o que você deseja, usando qualquer awk em qualquer shell em cada caixa UNIX:
$ cat tst.awk
/^[0-9]/ { prt() }
{ rec = rec $0 ORS }
END { prt() }
function prt() {
if ( rec ~ regexp ) {
printf "%s", rec
}
rec = ""
}
.
$ awk -v regexp='issue' -f tst.awk file
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.