Grep due file e stampa righe con più risultati
Ho due file.
file1.txtabc def ghi jkl mno pqrfile2.txtabc ghi abc xyz xyz xyz mno jkl def stu
(il separatore di colonna è una tabulazione)
Sto cercando di grep il file1.txtcontro in file2.txtquesto modo:
grep -w -f file1.txt file2.txt
e ottengo il seguente output:
abc ghi
abc xyz
mno jkl
def stu
Tuttavia, quello che voglio è l'output in cui sia la colonna 1 che la colonna 2 file2.txthanno hit file1.txt, in questo modo:
abc ghi
mno jkl
Qualsiasi aiuto sarebbe il benvenuto.
Grazie.
Dan
Risposte
Salva ogni valore di file1.txtin un array a. Quindi, analizza file2.txte stampa le righe che hanno sia il primo che il secondo campo a.
awk 'NR==FNR{a[$0];next}$1 in a && $2 in a' file1.txt file2.txt
Per un numero arbitrario di campi in file2.txt, scorrere tutti i campi ed eseguire il controllo. Se uno dei campi non è presente a, passa alla riga successiva, altrimenti stampa la riga.
awk 'NR==FNR{a[$0];next}{for(i=1;i<=NF;i++){if(!($i in a)){next}}print}' file1.txt file2.txt
Usando pythonpossiamo avvicinarci al pbm creando un superset bche comprende gli elementi di file1.txt.
Quindi per ogni riga da leggere file2.txtcontrolliamo se l'insieme formato da questa riga corrente è un sottoinsieme del superset b. In tal caso stampiamo la riga corrente di 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 memorizziamo file1.txt nello spazio di attesa e quindi per ogni riga letta da File2.txt confrontiamo con la presenza di TUTTI gli elementi della riga corrente e stampiamo quando tutti trovati.
$ 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