
Tengo un archivo de texto del siguiente tipo,
a b c d
-- -- -- --
1 ok device issue Some Action which
has to be taken which
is split into many lines
under d.
Intenté usar grep para "problema", sin embargo, solo se imprime la primera línea de 'd'. El resultado que obtuve es:
1 ok device issue Some Action which
Sin embargo, quiero el resultado completo en d. Cuando intenté guardar el archivo en csv, mostró la segunda línea de la columna d como una nueva línea.
Editar:
El resultado se obtiene de varios dispositivos que se almacenan en una variable de la que estoy buscando aquellos que tienen problemas.
Respuesta1
Necesita grepping de varias líneas aquí. Para lo cual necesitaremos la -P
opción PCRE habilitada. Dado que grep generará registros delimitados por nulos en el -z
modo slurp, los eliminamos mediante el comando tr.
$ < file grep -Pzo '.*\S.*issue.*\n(?:\h+.*\n)+' | tr -d '\0'
Respuesta2
grep
está actuando como debería en el modo predeterminado. Desde su man
página:
...grep busca PATRONES en cada ARCHIVO. PATTERNS son uno o más patrones separados por caracteres de nueva línea, y grep imprime cada línea que coincide con un patrón...
Entonces, se supone que debe aparecer.líneasen el texto que coincide con un regex
. Las líneas están delimitadas por el newline
código de control, que explica el comportamiento que está viendo. Aparte de usar la -z
opción mencionada en las respuestas. Suponiendo que "problema" es la expresión regular que desea hacer coincidir (reemplace con 'Device Degraded'
o '\sDegraded'
o '\sError'
si eso es lo que realmente busca hacer coincidir); y que la columna "Acción correctiva" está generada por máquina y es consistente, es decir, siempre abarca 4 líneas y también puede simplemente ejecutarla grep -A 3 '\sissue' > issues
para guardar.solo las líneas que te interesanen un archivo. Debe poder generar una salida que se vea así:
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.
consulte la página de manual de grep para obtener más información sobre lo que hacen estas opciones.
Respuesta3
Suponiendo que un "registro" en el archivo de entrada es exactamente el proporcionado por el 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.
$
Respuesta4
Esto podría ser lo que deseas, usando cualquier awk en cualquier shell en cada caja 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.