
Ich habe zwei Dateien.
file1.txt
abc def ghi jkl mno pqr
file2.txt
abc ghi abc xyz xyz xyz mno jkl def stu
(Spaltentrennzeichen ist Tabulator)
Ich versuche, das file1.txt
Gegenstück file2.txt
ungefähr so zu greppen:
grep -w -f file1.txt file2.txt
und ich erhalte die folgende Ausgabe:
abc ghi
abc xyz
mno jkl
def stu
Was ich jedoch möchte, ist die Ausgabe, bei derbeideSpalte 1 und Spalte 2 von file2.txt
haben Treffer in file1.txt
, wie folgt:
abc ghi
mno jkl
Jede Hilfe ist willkommen.
Danke.
Dan
Antwort1
Speichern Sie jeden Wert von file1.txt
in einem Array a
. Analysieren file2.txt
und drucken Sie dann die Zeilen, die sowohl das 1. als auch das 2. Feld in enthalten a
.
awk 'NR==FNR{a[$0];next}$1 in a && $2 in a' file1.txt file2.txt
Führen Sie für eine beliebige Anzahl von Feldern in file2.txt
eine Schleife über alle Felder aus und führen Sie die Prüfung durch. Wenn eines der Felder nicht in enthalten ist a
, fahren Sie mit der nächsten Zeile fort, andernfalls drucken Sie die Zeile.
awk 'NR==FNR{a[$0];next}{for(i=1;i<=NF;i++){if(!($i in a)){next}}print}' file1.txt file2.txt
Antwort2
Mithilfe von python
können wir uns dem PBM nähern, indem wir eine Obermenge erstellen b
, die aus den Elementen von besteht file1.txt
.
Dann file2.txt
prüfen wir für jede gelesene Zeile, ob die aus dieser aktuellen Zeile gebildete Menge eine Teilmenge der Obermenge b ist. In diesem Fall drucken wir die aktuelle Zeile von 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
Mit sed speichern wir file1.txt im Haltebereich und vergleichen dann jede aus File2.txt gelesene Zeile mit dem Vorhandensein ALLER Elemente der aktuellen Zeile und drucken, wenn alle gefunden wurden.
$ 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