Tengo dos archivos file1y file2.
El contenido de la muestra file1es:
A B
C D
E F
G H
y el contenido de file2es como:
A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H
Por lo tanto, quiero buscar solo en todo el bloque de file1contenido file2. Esto significa que la salida debe contener solo estas líneas:
A B
C D
E F
G H
tenga en cuenta que: - solo las líneas que se unen deben ser parte de la salida.
shell-script
text-processing
awk
sed
sachin
fuente
fuente

file1y nada más, solo usecat file1.Respuestas:
grepes bastante estúpido cuando se trata de patrones multilínea, pero la traducción de todos los caracteres\nde nueva línea tanto del patrón como del texto para buscar caracteres NUL\0antes de compararlos soluciona esto. Obviamente, también es necesario traducir\0la salida a\nAquí está su comando, suponiendo que
file1contiene el patrón en el que desea buscarfile2:Ejemplo de salida para sus archivos dados:
Explicación:
<(tr '\n' '\0' < file1)crea un objeto FIFO / canalización con nombre / archivo temporal que es igualfile1, pero con todos los caracteres de nueva línea traducidos a caracteres NUL.<(tr '\n' '\0' < file2)hace lo mismo, pero parafile2.grep -f PATTERN_FILE INPUT_FILEbusca los patrones dePATTERN_FILEinINPUT_FILE.-aindicador degrephabilita la coincidencia en archivos binarios. Esto es necesario porque de lo contrario se omitiría los archivos que contienen caracteres no imprimibles como\0.-oindicador degrephace que imprima solo la secuencia coincidente, no la línea completa donde se ha encontrado.| tr '\0' '\n'traduce todos los caracteres NUL de la salida del comando en el lado izquierdo a caracteres de nueva línea.fuente
Lo siguiente es torpe, pero funciona con GNU
awk:fuente
Solo por diversión en pura fiesta
fuente
Aquí hay un poco más elegante
grep+perl:Sin embargo, hay una gran trampa. Si hay un salto de línea final en
file1, el patrón no será correcto, en otras palabras:A B\nC D\nE F\nG H\n\n.(Un agradecimiento especial @terdon por proporcionar la parte perl)
Como señaló Costas, se puede usar
perl -0pe 's/\n(\n+$)?/\\n/g'en lugar del otroperlcomando para evitar la nueva línea final en elfile1.txtfuente
perl -0pe 's/\n(\n+$)?/\\n/g'. Sin-0elgmodificador regex es extra.No estoy muy seguro de qué desea que sea la salida, pero es fácil de hacer con lenguajes que no están exclusivamente orientados a líneas (especialmente si ambos archivos se pueden leer en la memoria). Aquí hay un script de Python que le dirá cuántas coincidencias hay.
¿Desea imprimir
file1tantas veces como corresponda? Reemplace la última línea con esto:Puede empaquetar todo en una llamada de línea de comando o un alias, si realmente desea:
fuente
el resultado será todos los archivos con coincidencia exacta de texto
fuente
Aquí hay otro enfoque usando python (probado con
python3 3.5.2, sin quejas depylint3 1.5.6):El manejo de los argumentos de la línea de comando a través
sys.argves ciertamente simplista. Podría hacer muchas otras cosas con el valor de retorno definderlos dosmemoryviewobjetos que pasa, además de pasarlotuple. CadaSRE_Matchelemento generado por el iterador devuelto porfindertiene una variedad de métodos, una muestra de los cuales se resume en laprintsalida (elspan, por ejemplo, indica el rango de bytes de cada coincidencia).fuente