Linien drucken in eine Datei übereinstimmende Muster in einer anderen Datei
Habe ich eine Datei mit mehr als 40.000 Zeilen (Datei1) und ich möchte, um die Zeilen zu extrahieren passenden Muster in Datei2 (über 6000 Zeilen). Ich benutze grep, wie diese, aber es ist sehr langsam:
grep -f file2 file1 > out
Gibt es einen schnelleren Weg, dies zu tun mit awk
oder sed
?
Hier einige Auszüge aus meinen Dateien:
File1:
scitn003869.2| scign003869 CGCATGTGTGCATGTATTATCGTATCCCTTG
scitn007747.1| scign007747 CACGCAGACGCAGTGGAGCATTCCAGGTCACAA
scitn003155.1| scign003155 TAAAAATCGTTAGCACTCGCTTGGTACACTAAC
scitn018252.1| scign018252 CGTGTGTGTGCATATGTGTGCATGCGTG
scitn004671.2| scign004671 TCCTCAGGTTTTGAAAGGCAGGGTAAGTGCT
File2:
scign000003
scign000004
scign000005
scign004671
scign000013
`
Du musst angemeldet sein, um einen Kommentar abzugeben.
Versuchen
grep -Fwf file2 file1 > out
Den
-F
option gibt an einfachen string-matching, so sollte schneller sein, ohne dass man sich mit dem regex-engine.Hier ist, wie es in awk:
Mithilfe eines 60.000-line File1 (Ihr Datei1 wiederholt 8000 mal) und ein 6.000 Datei2 (Ihre wiederholten 1200 mal):
d.h. es ist in etwa so schnell wie die grep. Eine Sache zu beachten ist jedoch, dass die awk-Lösung, können Sie wählen Sie einen bestimmten Bereich für die übereinstimmung so, wenn etwas aus Datei2 zeigt sich nirgendwo sonst in Datei1 Sie nicht bekommen eine falsche übereinstimmung. Außerdem können Sie auf ein ganzes Gebiet zu einem Zeitpunkt also, wenn Ihr Ziel-strings wurden in verschiedenen Längen und Sie wollte nicht, dass "scign000003" passend "scign0000031" zum Beispiel (obwohl das -w für grep gibt vergleichbaren Schutz für die).
Vollständigkeit halber, hier ist das timing für die anderen awk-Lösung gepostet elsethread:
und hier ist das timing bekomme ich für das perl-Skript Daneben geschrieben:
Könnten Sie versuchen, mit diesem awk:
Den
FNR==NR
Teil gibt an, dass die Sachen in geschweiften Klammern ist nur angewendet werden, wenn die Verarbeitung der ersten Eingabedatei (file2
). Und es sagt, zu speichern Sie alle Wörter, die Sie suchen in einem arraya[]
. Das bit in dem zweiten Satz von geschweiften Klammern gilt für die Verarbeitung von in der zweiten Datei... da ist jede Zeile zu Lesen ist, ist es im Vergleich mit allen Elementen vona[]
und wenn welche gefunden werden, wird die Zeile gedruckt. That ' s all folks!if (index($0, a[j]) {print; break}
Nur zum Spaß, hier ist eine Perl-version:
Hier sind einige timings, mit einem 60.000 line file1 und 6.000 Zeile Datei2 pro Ed-s Datei erstellen Methode:
awk
Lösung.. übrigens, ich vermute, Sie rettete die Ausgabe des perl-Programm auch eine Datei? (Es gibt keine Umleitung nach./go.pl
im Sie Antwort)Nur für die Zwecke des Lernens: ich war der Lösung das gleiche problem und ich kam mit verschiedenen Lösungen (einschließlich
read $line
loops etc..). Wenn ich an diegrep
one-liner, die oben gefunden werden, noch ich am Ende immer die falsche Ausgabe. Dann erkannte ich meine MUSTER-Datei hatte 2 hinteren Linien... Sogrep
abgeholt, alle meine Zeilen aus meiner Datenbank. Moral: überprüfen Sie die Leerzeichen/Zeilen. Auch lief der Befehl auf einem viel größeren Datenmenge mit mehreren Hunderten von mustern undtime
konnte nicht einmal zählen.grep -Fwf <(grep '[^[:blank]]' file2) file1
werden nur Zeilen mit einem nicht-Leerzeichen.