Tengo varios archivos de texto con este formato:
name: john
address: bay area
phone: 6505561234
image: /work/myimage.png
name: stark
dob: 5AD
shirt color: red
physical address: Westros
phone model: S2
email id: [email protected]
phone model: S2
name: tara
dob: 1ad
shirt color: red
physical address: Westros
email id: [email protected]
Puede haber múltiples 'persona o' contacto '. Digamos que quiero encontrar a todas las personas con el modelo de teléfono 'S2'.
Puedo hacer un 'grep', eso solo devolvería esto:
phone model: S2
phone model: S2
Puedo usar el contexto antes / después en grep, pero eso es solo un número fijo de líneas antes / después que se imprimen. Con un contexto 'anterior' de 3, podría obtener algo como esto:
shirt color: red
physical address: Westros
phone model: S2
---
name: tara
dob: 1ad
phone model: S2
Pero eso no es lo que quiero. Quiero que aparezca todo el 'registro'. ¿Alguna pista sobre cómo hacer esto con los comandos estándar de Unix?
awk
, pero, sinceramente, sería más fácil hacerlo con otras herramientas. ¿Por qué necesita herramientas estándar de Unix? ¿Puedes usar un lenguaje de scripting como Ruby o Python también? Esos a menudo vienen con todo tipo de distribuciones de Linux.Respuestas:
awk 'BEGIN {RS="\n\n"} $0 ~ /PATTERN/ {print $0"\n---"}' record
Simplemente reemplace PATTERN con lo que quiera.
fuente
Si reemplaza sus líneas vacías con
---
, su documento es un archivo YAML válido. Esto representa muy bien una estructura de registro como la que tienes.Luego, para obtener los registros completos:
Esto imprime:
Marcado como CW ya que estaba pidiendo herramientas estándar de Unix, que
ruby
obviamente no lo es. Funciona con Ruby 1.8.7, 1.9.3 y 2.0.0.fuente
Usando esta pregunta, consigo encontrar una manera de hacer un grep multilínea para los bloques:
donde
(..*\n)*
hay cualquier número de líneas contagiosas no vacías.-P
habilita la sintaxis de perl,-z
permite búsquedas de nueva línea e-o
imprime solo las coincidencias. Sed se usa para la separación y la cola corta la primera línea.fuente
this format
significar 1. todos los registros comienzan con el nombre de la clave 2. todas las claves están escritas en su propia línea 3. los registros están separados por una línea vacía. Mi solución funciona bien para eso.La solución con awk es bastante clara. Aquí hay una posible solución con sed:
fuente
Los registros separados por líneas en blanco son en realidad un formato común para los archivos de fortuna, y (al menos en la versión de fortune que tengo, fortune-mod en Arch Linux) hay una
-m
opción que imprime todas las fortunas (registros) que coinciden con una expresión regular. Entonces algo como esto:e imprimirá todos sus registros.
fuente