it-swarm.com.de

Wie extrahiere ich ungewöhnlichen, nicht zwischen Groß- und Kleinschreibung unterscheidenden Text aus zwei Dateien?

Ich versuche ungewöhnlichen Text aus der Datei zu extrahieren und habe Folgendes versucht:

awk 'FNR==NR {a[$0]++; next} !a[$0]' 1.txt 2.txt
http://PQR.com
http://example.com

Hier sind die Eingabedateien:

File: 1.txt
http://google.com
http://GOOGLE.com
http://example1.com
http://seperate.com
http://pqr.com
File: 2.txt
http://PQR.com
http://example.com
http://google.com

Wie du sehen kannst, http://pqr.com ist verfügbar in Datei 1.txt und http://PQR.com im 2.txt. und die Ergebnisanzeige http://PQR.com, was in beiden Dateien gleich ist. Wie kann ich also nur den ungewöhnlichen Text anzeigen (unabhängig von den Fällen des Textes)?

4
Jaffer Wilson

Da Sie bereits awk verwenden, verwenden Sie tolower, um die Zeilen in Kleinbuchstaben zu schreiben:

awk 'FNR==NR {a[tolower($0)]++; next} !a[tolower($0)]' foo bar

Dies druckt jedoch nur Zeilen in bar, die sich nicht in foo befanden.

Vergleichen mit:

$ sort -f bar foo | uniq -iu
http://example.com
http://example1.com
http://seperate.com

Mit awk müssen Sie auch jede Zeile drucken, die nur einmal gesehen wurde:

$ awk '{a[tolower($0)]++} END {for (i in a) if (a[i] == 1) print i}' foo bar
http://seperate.com
http://example.com
http://example1.com
7
muru

Hier ist eine Python Lösung mit einer effizienten Set-Implementierung für Nice [~ # ~] o [~ # ~] ( n + m ) Leistung (mit n und m sind die Größen der beiden Eingabedateien).

Code

#!/usr/bin/python3
import sys

with open(sys.argv[1]) as A_file:
    A = frozenset(map(str.casefold, map(str.rstrip, A_file)))

with open(sys.argv[2]) as B_file:
    B = map(str.rstrip, B_file))
    B_minus_A = filter(lambda s: s.casefold() not in A, B)
    print(*B_minus_A, sep='\n')

Anwendungsbeispiel

python3 casefold-difference.py 1.txt 2.txt

Erläuterung

  • Das Programm verwendet casefold für den Zeichenfolgenvergleich, gibt jedoch die Zeilen zurück, wie sie in 2.txt Erscheinen. Das Falten von Groß- und Kleinschreibung wird empfohlen, um einen Vergleich der natürlichen Sprache ohne Berücksichtigung der Groß- und Kleinschreibung durchzuführen. Wenn Sie dies nicht möchten (da URLs keine natürliche Sprache sind), können Sie sie durch lower ersetzen.

  • Wenn 2.txt Eine große Anzahl von Zeilen enthält (die nicht in 1.txt Erscheinen), kann die Erstellung der Liste der variablen Argumente in der letzten Anweisung sehr viel Speicher beanspruchen, und Sie sind möglicherweise besser off, um es durch eine Schleife zu ersetzen:

    for item in B_minus_A:
        print(item)
    
4
David Foerster

Dies ist ein ziemlich einfacher Job für grep:

grep -viFf file2.txt file1.txt
  • -v zeigt die Zeilen, die nicht übereinstimmen
  • -i aktiviert die Unterscheidung zwischen Groß- und Kleinschreibung
  • -F macht Muster wörtlich
  • -f file1.txt liest die passenden Muster aus file1.txt, Zeile für Zeile

Beispiel:

% cat file1.txt 
http://google.com
http://GOOGLE.com
http://example1.com
http://seperate.com
http://pqr.com

% cat file2.txt 
http://PQR.com
http://example.com
http://google.com

% grep -viFf file2.txt file1.txt
http://example1.com
http://seperate.com
4
heemayl