
Tengo dos archivos.
file1.txt
abc def ghi jkl mno pqr
file2.txt
abc ghi abc xyz xyz xyz mno jkl def stu
(el separador de columnas es una pestaña)
Estoy tratando de agarrar el file1.txt
contra file2.txt
de esta manera:
grep -w -f file1.txt file2.txt
y obtengo el siguiente resultado:
abc ghi
abc xyz
mno jkl
def stu
Sin embargo, lo que quiero es la salida dondeambosla columna 1 y la columna 2 file2.txt
tienen visitas en file1.txt
, así:
abc ghi
mno jkl
Cualquier ayuda sera bienvenida.
Gracias.
Dan
Respuesta1
Guarde cada valor de file1.txt
en una matriz a
. Luego, analice file2.txt
e imprima las líneas que tienen el primer y el segundo campo en formato a
.
awk 'NR==FNR{a[$0];next}$1 in a && $2 in a' file1.txt file2.txt
Para un número arbitrario de campos en file2.txt
, recorra todos los campos y realice la verificación. Si uno de los campos no está en a
, continúe con la siguiente línea; de lo contrario, imprima la línea.
awk 'NR==FNR{a[$0];next}{for(i=1;i<=NF;i++){if(!($i in a)){next}}print}' file1.txt file2.txt
Respuesta2
Usando python
podemos acercarnos al pbm creando un superconjunto b
que comprende los elementos de file1.txt
.
Luego, para cada línea leída, file2.txt
verificamos si el conjunto formado a partir de esta línea actual es un subconjunto del superconjunto b. En cuyo caso imprimimos la línea actual de file2.txt`
$ python3 -c 'import sys
f1, f2 = sys.argv[1:]
with open(f1) as fh1, open(f2) as fh2:
b = set([l.strip() for l in fh1])
print(*(l.rstrip() for l in fh2 if set(l.strip().split()).issubset(b)), sep="\n")
' file1.txt file2.txt
abc ghi
mno jkl
$ perl -lane '$. == 1 and
%h = map { /(.*)(\n)/ } <STDIN>;
print if ! grep { ! $h{$_} } @F;
' file2.txt < file1.txt
Usando sed almacenamos file1.txt en el espacio de retención y luego, para cada línea leída de File2.txt, comparamos la presencia de TODOS los elementos de la línea actual e imprimimos cuando se encuentran todos.
$ sed -Ee '
/\n/{h;d;}
/\s/!{H;d;}
G;h
s/\n.*//;s/\n//;x
:a
s/^\s?(\S+)((\s\S+)?\n.*\n\1(\n|$))/\2/
ta
s/^\n//;tb
D;:b;x
' file1.txt file2.txt
while IFS= read -r l <&3; do
read -r a b <<<"$l"
grep -qFe "$a" file1.txt &&
grep -qFe "$b" file1.txt &&
printf '<%s>\n' "$l"
done 3< file2.txt