Tengo dos archivos file1
y file2
.
El contenido de la muestra file1
es:
A B
C D
E F
G H
y el contenido de file2
es 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 file1
contenido 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
file1
y nada más, solo usecat file1
.Respuestas:
grep
es bastante estúpido cuando se trata de patrones multilínea, pero la traducción de todos los caracteres\n
de nueva línea tanto del patrón como del texto para buscar caracteres NUL\0
antes de compararlos soluciona esto. Obviamente, también es necesario traducir\0
la salida a\n
Aquí está su comando, suponiendo que
file1
contiene 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_FILE
busca los patrones dePATTERN_FILE
inINPUT_FILE
.-a
indicador degrep
habilita la coincidencia en archivos binarios. Esto es necesario porque de lo contrario se omitiría los archivos que contienen caracteres no imprimibles como\0
.-o
indicador degrep
hace 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 otroperl
comando para evitar la nueva línea final en elfile1.txt
fuente
perl -0pe 's/\n(\n+$)?/\\n/g'
. Sin-0
elg
modificador 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
file1
tantas 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.argv
es ciertamente simplista. Podría hacer muchas otras cosas con el valor de retorno definder
los dosmemoryview
objetos que pasa, además de pasarlotuple
. CadaSRE_Match
elemento generado por el iterador devuelto porfinder
tiene una variedad de métodos, una muestra de los cuales se resume en laprint
salida (elspan
, por ejemplo, indica el rango de bytes de cada coincidencia).fuente