it-swarm.com.de

Zwei Textdateien vergleichen

Ich habe 2 große CSV-Dateien, file1.csv, die so aussehen

1,2,3,4
1,4,5,6
1,7,8,9
1,11,13,17

file2.csv was so aussieht

1,2,3,4
1,7,8,9
2,4,9,10
13,14,17,18

Dies sind nur Zufallszahlen, die ich erfunden habe. Im Grunde genommen waren die beiden Zahlen identisch und sortiert. Ich möchte file1.csv und file2.csv vergleichen und dann die Zeilen, die in file1.csv, aber nicht in file2.csv vorhanden sind, in file3.csv kopieren. Das Trennzeichen ist offensichtlich Komma

Ich habe es versucht

comm -2 -3 file.csv file2.csv > file3.csv

und ich versuchte es

diff -u file.csv file2.csv >> file3.csv

Beides hat nicht funktioniert, weil file3 größer als file1 und file2 war. Ich habe verschiedene diff und comm Befehle ausprobiert. Manchmal ist es größer als Datei2 und ungefähr so ​​groß wie Datei1. Ich weiß, dass Datei3 bedeutend kleiner sein muss als Datei1 und Datei2. Und natürlich habe ich mir file3 angesehen, nicht die Ergebnisse, die ich haben wollte

Zum jetzigen Zeitpunkt weiß ich, dass dies mit diff oder comm möglich ist, aber ich kenne den zu verwendenden Befehl nicht.

6
Lynob

Versuchen Sie diesen Befehl:

 grep -v -f file2.csv file1.csv > file3.csv

Nach grep manual :

  -f FILE, --file=FILE
          Obtain  patterns  from  FILE,  one  per  line.   The  empty file
          contains zero patterns, and therefore matches nothing.   (-f  is
          specified by POSIX.)

  -v, --invert-match
          Invert the sense of matching, to select non-matching lines.  (-v
          is specified by POSIX.)

Wie Steeldriver in seinem Kommentar sagte, ist es besser, auch -x und -F hinzuzufügen, dass:

  -F, --fixed-strings
          Interpret PATTERN as a  list  of  fixed  strings,  separated  by
          newlines,  any  of  which is to be matched.  (-F is specified by
          POSIX.)
  -x, --line-regexp
          Select  only  those  matches  that exactly match the whole line.
          (-x is specified by POSIX.)

Ein besserer Befehl ist also:

 grep -xvFf file2.csv file1.csv > file3.csv

Dieser Befehl verwendet die Zeile file2.csv als Muster und Druckzeile von file1.csv, die nicht übereinstimmt (-v).

6
Lety

Um comm verwenden zu können, müssen Sie zuerst die Zeilen sortieren.

comm -23 <(sort file1.csv) <(sort file2.csv) > file3.csv
7
choroba

Verwenden Sie den Befehl diff, um grep auszuführen, und es ist keine Speicherung erforderlich.

Ausgabe, wenn Zeilen in Datei1, aber nicht in Datei2 vorhanden sind:

$ diff file{1,2}.csv | grep -Po "^< \K.*"
1,4,5,6
1,11,13,17

Und ausgegeben, wenn Linien in Datei2, aber nicht in Datei1 vorhanden sind, wobei nur der linke Winkel (<) in den rechten Winkel (>) geändert wird:

$ diff file{1,2}.csv | grep -Po "^> \K.*"
2,4,9,10
13,14,17,18
3
αғsнιη

Eine python Option:

#!/usr/bin/env python3

import sys

def readfile(file):
    with open(file) as src:
        return [line.strip() for line in src.readlines()]

lines_1 = readfile(sys.argv[1]); lines_2 = readfile(sys.argv[2])

for line in lines_1:
    if not line in lines_2:
        print(line)

Ausgabe:

1,4,5,6
1,11,13,17

Fügen Sie das Skript als extract.py in eine leere Datei ein, machen Sie es ausführbar und führen Sie es mit dem folgenden Befehl aus:

<script> <file_1> <file_2>

Oder, um es direkt in file_3 zu schreiben:

<script> <file_1> <file_2> >file_3
3
Jacob Vlijm