Ich habe zwei Dateien file1
und file2
.
Der Beispielinhalt von file1
ist:
A B
C D
E F
G H
und der Inhalt von file2
ist wie:
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
Ich möchte also nur den gesamten file1
Inhaltsblock durchsuchen file2
. Dies bedeutet, dass die Ausgabe nur die folgenden Zeilen enthalten sollte:
A B
C D
E F
G H
Bitte beachten Sie Folgendes: - Nur die Zeilen, die zusammenkommen, sollten Teil der Ausgabe sein.
shell-script
text-processing
awk
sed
Sachin
quelle
quelle
file1
und nichts anderes drucken möchten , verwenden Sie einfachcat file1
.Antworten:
grep
ist ziemlich dumm, wenn es um mehrzeilige Muster geht, aber das Übersetzen aller Zeilenumbrüche\n
sowohl des Musters als auch des Textes, um\0
vor dem Vergleich in NUL-Zeichen zu suchen , behebt dies. Eine Rückübersetzung\0
in die Ausgabe nach\n
ist natürlich ebenfalls erforderlich.Hier ist Ihr Befehl, vorausgesetzt, er
file1
enthält das Muster, in dem Sie suchen möchtenfile2
:Beispielausgabe für Ihre angegebenen Dateien:
Erläuterung:
<(tr '\n' '\0' < file1)
Erstellt ein FIFO /file1
Named Pipe / temporäres dateiähnliches Objekt, das gleich ist , wobei jedoch alle Zeilenumbruchzeichen in NUL-Zeichen übersetzt werden.<(tr '\n' '\0' < file2)
macht das gleiche, aber fürfile2
.grep -f PATTERN_FILE INPUT_FILE
sucht nach den Mustern vonPATTERN_FILE
inINPUT_FILE
.-a
Flag vongrep
aktiviert den Abgleich für Binärdateien. Dies ist erforderlich, da sonst Dateien übersprungen werden, die nicht druckbare Zeichen enthalten, wie z\0
.-o
Flag vongrep
wird nur die übereinstimmende Sequenz gedruckt, nicht die gesamte Zeile, in der sie gefunden wurde.| tr '\0' '\n'
übersetzt alle NUL-Zeichen von der Ausgabe des Befehls auf der linken Seite zurück in Zeilenumbruchzeichen.quelle
Folgendes ist ungeschickt, funktioniert aber mit GNU
awk
:quelle
Nur zum Spaß in purer Bash
quelle
Hier ist ein bisschen eleganter
grep
+perl
:Es gibt jedoch einen großen Haken. Wenn ein nachfolgender Zeilenumbruch vorhanden ist
file1
, ist das Muster nicht korrekt, mit anderen Worten :A B\nC D\nE F\nG H\n\n
.(Besonderer Dank geht an @terdon für die Bereitstellung des Perl-Teils)
Wie bereits erwähnt, kann
perl -0pe 's/\n(\n+$)?/\\n/g'
anstelle des anderenperl
Befehls der nachfolgende Zeilenumbruch im verwendet werdenfile1.txt
quelle
perl -0pe 's/\n(\n+$)?/\\n/g'
. Ohne-0
deng
Regex-Modifikator ist extra.Ich bin mir nicht sicher, wie die Ausgabe aussehen soll, aber es ist einfach, Sprachen zu verwenden, die nicht ausschließlich zeilenorientiert sind (insbesondere, wenn beide Dateien in den Speicher eingelesen werden können). Hier ist ein Python-Skript, das Ihnen sagt, wie viele Übereinstimmungen es gibt.
Sie möchten
file1
so oft drucken, wie es passt? Ersetzen Sie die letzte Zeile durch:Sie können alles in einen Befehlszeilenaufruf oder Alias packen, wenn Sie wirklich möchten:
quelle
Das Ergebnis sind alle Dateien mit exakter Textübereinstimmung
quelle
Hier ist ein anderer Ansatz mit Python (getestet mit
python3 3.5.2
, ohne Beschwerden vonpylint3 1.5.6
):Der Umgang mit Kommandozeilenargumenten über
sys.argv
ist zugegebenermaßen vereinfacht. Sie können viele andere Dinge mit dem Rückgabewert vonfinder
für die beidenmemoryview
Objekte tun, die Sie übergeben, außer es an zu übergebentuple
. JedesSRE_Match
Element, das von dem von zurückgegebenen Iterator ausgegeben wird,finder
verfügt über eine Vielzahl von Methoden, von denen eine Stichprobe in derprint
Ausgabe zusammengefasst ist (diespan
beispielsweise den Bytebereich jeder Übereinstimmung angibt).quelle