
Eu tenho dois arquivos.
file1.txt
abc def ghi jkl mno pqr
file2.txt
abc ghi abc xyz xyz xyz mno jkl def stu
(separador de coluna é tabulação)
Estou tentando fazer o grep file1.txt
contra file2.txt
algo assim:
grep -w -f file1.txt file2.txt
e recebo a seguinte saída:
abc ghi
abc xyz
mno jkl
def stu
No entanto, o que eu quero é a saída ondeamboscoluna 1 e coluna 2 de file2.txt
têm ocorrências em file1.txt
, assim:
abc ghi
mno jkl
Qualquer ajuda é bem vinda.
Obrigado.
Dan
Responder1
Salve cada valor file1.txt
em um array a
. Em seguida, analise file2.txt
e imprima as linhas que possuem o primeiro e o segundo campo em a
.
awk 'NR==FNR{a[$0];next}$1 in a && $2 in a' file1.txt file2.txt
Para um número arbitrário de campos em file2.txt
, faça um loop em todos os campos e execute a verificação. Se um dos campos não estiver em a
, continue para a próxima linha, caso contrário imprima a linha.
awk 'NR==FNR{a[$0];next}{for(i=1;i<=NF;i++){if(!($i in a)){next}}print}' file1.txt file2.txt
Responder2
Usando python
podemos abordar o pbm criando um superconjunto b
que compreende os elementos de file1.txt
.
Então, para cada linha lida, file2.txt
verificamos se o conjunto formado a partir desta linha atual é um subconjunto do superconjunto b. Nesse caso, imprimimos a linha atual 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 armazenamos file1.txt no espaço de espera e então para cada linha lida de File2.txt comparamos com a presença de TODOS os elementos da linha atual e imprimimos quando todos encontrados.
$ 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