A continuación se muestra el texto en el archivo:
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
Necesito grep para "42B" y obtener el resultado del texto anterior como:
Pseudo name=Apple
Code=42B
state=fault
¿Alguien tiene idea de cómo lograr esto usando grep
/ awk
/ sed
?
Respuestas:
Con
awk
RS=
cambia el separador de registro de entrada de una nueva línea a líneas en blanco. Si algún campo en un registro contiene/42B/
imprimir el registro.''
(la cadena nula) es un valor mágico utilizado para representar líneas en blanco según POSIX :Los párrafos de salida no se separarán ya que el separador de salida sigue siendo una nueva línea. Para asegurarse de que haya una línea en blanco entre los párrafos de salida, establezca el separador de registro de salida en dos líneas nuevas:
fuente
FILENAME
), no es una mala idea usar la redirección, ya que evita problemas para el nombre de archivo que contiene=
o comienza con-
(o es-
), genera mensajes de error consistentes y evita ejecutarawk
o ejecutar otras redirecciones si el archivo de entrada no se puede abrir.Suponiendo que los datos están estructurados de modo que siempre sea la línea anterior y posterior a la que desea, puede usar los interruptores grep
-A
(after) y-B
(before) para indicar que incluya la línea 1 antes del partido y la línea 1 después:Si desea las mismas líneas numéricas antes y después del término de búsqueda, puede usar el
-C
interruptor (contexto):Si desea ser más estricto al hacer coincidir las líneas múltiples, puede usar la herramienta
pcregrep
, para hacer coincidir un patrón en varias líneas:El patrón anterior coincide de la siguiente manera:
-M
- líneas múltiples'Pseudo.*\n.*42B.*\nstate.*'
- coincide con un grupo de cadenas donde la primera cadena comienza con la palabra"Pseudo"
seguida de cualquier carácter hasta el final de la línea\n
, seguido de cualquier carácter hasta la cadena"42B"
seguido de cualquier carácter hasta el otro extremo de la línea (\n
), seguido de la cadena"state"
seguido de cualquier personaje.fuente
-C
(contexto) puede usarse como un acceso directo, si-A
y-B
son lo mismo.Probablemente haya una manera similar de hacerlo con awk, pero en perl:
Básicamente, eso dice dividir el archivo en fragmentos delimitados por líneas en blanco, luego solo imprimir esos fragmentos que coincidan con su expresión regular.
fuente
cat
;perl -00 -ne 'print if /42B/' file
El
grep
de algunos sabores de Unix tiene la-p
bandera de "párrafo". Sé que AIX sí .haría exactamente lo que estás pidiendo allí. YMMV y GNU grep no tienen esta bandera.
fuente
Otra solución perl, sin una línea vacía final:
Ejemplo
fuente
perl -00 -ne 'print if /42B/' file
.