it-swarm.com.de

Gemeinsame Linien zwischen zwei Dateien

Ich habe den folgenden Code, den ich auf meinem Terminal ausführe.

LC_ALL=C && grep -F -f  genename2.txt hg38.hgnc.bed > hg38.hgnc.goi.bed

Dies gibt mir nicht die gemeinsamen Linien zwischen den beiden Dateien. Was vermisse ich dort?

10
Marwah Soliman

Verwenden comm -12 file1 file2, um gemeinsame Zeilen in beiden Dateien zu erhalten.

Möglicherweise muss Ihre Datei auch nach comm sortiert werden, damit sie wie erwartet funktioniert.

comm -12 <(sort file1) <(sort file2)

Von man comm :

-1     suppress column 1 (lines unique to FILE1)
-2     suppress column 2 (lines unique to FILE2)

Oder mit dem Befehl grep müssen Sie -x Option, um die gesamte Linie als übereinstimmendes Muster abzugleichen. Die Option F teilt grep mit, dass das Übereinstimmungsmuster eine Zeichenfolge und keine Regex-Übereinstimmung ist.

grep -Fxf file1 file2

Oder mit awk.

awk 'NR==FNR{seen[$0]=1; next} seen[$0]' file1 file2

Dies liest die ganze Zeile von file1 In ein Array namens seen mit dem Schlüssel als ganze Zeile (in awk the $0 repräsentiert die gesamte aktuelle Zeile).

Wir verwendeten NR==FNR als Bedingung, um den folgenden Block nur für die erste Eingabe auszuführen fle1 not file2, weil NR in awk refer auf die aktuelle Verarbeitungszeilennummer und FNR bezieht sich auf die aktuelle Zeilennummer in all Eingaben. NR ist also für jede Eingabedatei eindeutig, aber FNR ist für alle Eingaben eindeutig.

Das next ist da und sagt awk, setz den Ruhecode nicht fort und beginne erneut, bis NR nicht gleich FNR ist, was bedeutet, dass alle Zeilen von file1 gelesen von awk.

Dann als nächstes seen[$0] wird nur für die Sekunde Datei2 ausgeführt und für jede Zeile in Datei2 wird in das Array geschaut und die Zeile gedruckt, in der sie im Array vorhanden ist.

Eine andere einfache Option ist die Verwendung von sort und uniq:

sort file1 file2|uniq -d

Dadurch werden beide Dateien sortiert und dann uniq -d druckt nur doppelte Zeilen. ABER dies wird gewährt, wenn in beiden Dateien selbst KEINE doppelten Zeilen vorhanden sind. Andernfalls wird unten immer gewährt, selbst wenn in beiden Dateien doppelte Zeilen vorhanden sind.

uniq -d <(sort <(sort -u file1) <(sort -u file2))
32
αғsнιη

Da Sie unter Linux laufen, ist es vermutlich GNU/Linux und Sie verwenden den Befehl GNU diff).

Wenn Sie den Befehl GNU diff) ausführen, werden auf diese Weise alle geänderten Zeilen sowie allgemeine Zeilen angezeigt:

diff \
--old-line-format='-%l
' \
--new-line-format='+%l
' \
--unchanged-line-format=' %l
' \
"[email protected]"

Dies ähnelt der klassischen Ausgabe von diff, es werden jedoch keine Dateinamen oder Trennzeilen in der Ausgabe angezeigt, und alte Zeilen werden mit - Markiert, neuen Zeilen wird + Und vorangestellt Gemeinsamen Zeilen wird ein Leerzeichen vorangestellt.

Hier ist ein Beispiel für ein Shell-Skript und die daraus resultierende Ausgabe in Testdateien:

$ cat diffcomm.sh
#!/bin/sh
diff \
--old-line-format='-%l
' \
--new-line-format='+%l
' \
--unchanged-line-format=' %l
' \
"[email protected]"
$ cat > filea
a
b
c
d
$ cat > fileb
a
z
d
$ ./diffcomm.sh  filea fileb
 a
-b
-c
+z
 d
$

Sie können das Ausgabeformat für jede Zeilenklasse ändern.

Weitere Informationen finden Sie unter man diff Oder info diff Oder in der GNU diffutils-Dokumentation .

3
RobertL