GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Linux-Tools zum Behandeln von Dateien als Sets und Ausführen von Set-Operationen an ihnen?

Kennt jemand ein Linux-Tool, das speziell dafür entwickelt wurde, Dateien als Sets zu behandeln und Set-Operationen an ihnen durchzuführen? Wie Differenz, Schnittmenge usw.?

Akzeptierte Antwort:

Angenommen, Elemente sind andere Zeichenketten als NUL und Newline (beachten Sie jedoch, dass Newline in Dateinamen gültig ist), können Sie eine Menge darstellen als Textdatei mit einem Element pro Zeile und verwenden Sie einige der Standard-Unix-Dienstprogramme.

Mitgliedschaft festlegen

$ grep -Fxc 'element' set   # outputs 1 if element is in set
                            # outputs >1 if set is a multi-set
                            # outputs 0 if element is not in set

$ grep -Fxq 'element' set   # returns 0 (true)  if element is in set
                            # returns 1 (false) if element is not in set

$ awk '$0 == "element" { s=1; exit }; END { exit !s }' set
# returns 0 if element is in set, 1 otherwise.

$ awk -v e='element' '$0 == e { s=1; exit } END { exit !s }'

Kreuzung festlegen

$ comm -12 <(sort set1) <(sort set2)  # outputs intersect of set1 and set2

$ grep -xF -f set1 set2

$ sort set1 set2 | uniq -d

$ join -t <(sort A) <(sort B)

$ awk '!done { a[$0]; next }; $0 in a' set1 done=1 set2

Gleichheit festlegen

$ cmp -s <(sort set1) <(sort set2) # returns 0 if set1 is equal to set2
                                   # returns 1 if set1 != set2

$ cmp -s <(sort -u set1) <(sort -u set2)
# collapses multi-sets into sets and does the same as previous

$ awk '{ if (!($0 in a)) c++; a[$0] }; END{ exit !(c==NR/2) }' set1 set2
# returns 0 if set1 == set2
# returns 1 if set1 != set2

$ awk '{ a[$0] }; END{ exit !(length(a)==NR/2) }' set1 set2
# same as previous, requires >= gnu awk 3.1.5

Kardinalität festlegen

$ wc -l < set     # outputs number of elements in set

$ awk 'END { print NR }' set

$ sed '$=' set

Subset-Test

$ comm -23 <(sort -u subset) <(sort -u set) | grep -q '^'
# returns true iff subset is not a subset of set (has elements not in set)

$ awk '!done { a[$0]; next }; { if !($0 in a) exit 1 }' set done=1 subset
# returns 0 if subset is a subset of set
# returns 1 if subset is not a subset of set

Vereinigung festlegen

$ cat set1 set2     # outputs union of set1 and set2
                    # assumes they are disjoint

$ awk 1 set1 set2   # ditto

$ cat set1 set2 ... setn   # union over n sets

$ sort -u set1 set2  # same, but doesn't assume they are disjoint

$ sort set1 set2 | uniq

$ awk '!a[$0]++' set1 set2       # ditto without sorting

Ergänzung festlegen

$ comm -23 <(sort set1) <(sort set2)
# outputs elements in set1 that are not in set2

$ grep -vxF -f set2 set1           # ditto

$ sort set2 set2 set1 | uniq -u    # ditto

$ awk '!done { a[$0]; next }; !($0 in a)' set2 done=1 set1

Symmetrische Differenz festlegen

$ comm -3 <(sort set1) <(sort set2) | tr -d 't'  # assumes not tab in sets
# outputs elements that are in set1 or in set2 but not both

$ sort set1 set2 | uniq -u

$ cat <(grep -vxF -f set1 set2) <(grep -vxF -f set2 set1)

$ grep -vxF -f set1 set2; grep -vxF -f set2 set1

$ awk '!done { a[$0]; next }; $0 in a { delete a[$0]; next }; 1;
       END { for (b in a) print b }' set1 done=1 set2

Power-Set

Alle möglichen Teilmengen einer Menge werden durch Leerzeichen getrennt angezeigt, eine pro Zeile:

$ p() { [ "$#" -eq 0 ] && echo || (shift; p "[email protected]") |
        while read r; do printf '%s %sn%sn' "$1" "$r" "$r"; done; }
$ p $(cat set)

(unter der Annahme, dass Elemente kein SPC, TAB enthalten (unter der Annahme des Standardwerts von $IFS ), Backslash, Platzhalterzeichen).

Verwandte:Welche Dateikomprimierungssoftware für Linux bietet die höchste Größenreduzierung?

Kartesisches Produkt festlegen

$ while IFS= read -r a; do while IFS= read -r b; do echo "$a, $b"; done < set1; done < set2

$ awk '!done { a[$0]; next }; { for (i in a) print i, $0 }' set1 done=1 set2

Disjunkter Mengentest

$ comm -12 <(sort set1) <(sort set2)  # does not output anything if disjoint

$ awk '++seen[$0] == 2 { exit 1 }' set1 set2 # returns 0 if disjoint
                                             # returns 1 if not

Leerer Set-Test

$ wc -l < set            # outputs 0  if the set is empty
                         # outputs >0 if the set is not empty

$ grep -q '^' set        # returns true (0 exit status) unless set is empty

$ awk '{ exit 1 }' set   # returns true (0 exit status) if set is empty

Minimum

$ sort set | head -n 1   # outputs the minimum (lexically) element in the set

$ awk 'NR == 1 { min = $0 }; $0 < min { min = $0 }; END { print min }'
# ditto, but does numeric comparison when elements are numerical

Maximal

$ sort test | tail -n 1    # outputs the maximum element in the set

$ sort -r test | head -n 1

$ awk '$0 > max { max = $0 }; END { print max }'
# ditto, but does numeric comparison when elements are numerical

Alle verfügbar unter http://www.catonmat.net/blog/set-operations-in-unix-shell-simplified/


Linux
  1. 5 Befehlszeilen-Tools zum schnellen Auffinden von Dateien unter Linux

  2. So archivieren und komprimieren Sie Dateien unter Linux

  3. Linux – In /dev/pts Dateien gespeichert und können wir sie öffnen?

  4. Linux – Standard- und/oder gemeinsame Verzeichnisse auf Unix/Linux-Betriebssystemen?

  5. Linux Dateien und Verzeichnisse löschen

So setzen und listen Sie Umgebungsvariablen in Linux auf

Die 3 besten Tools zum Suchen und Löschen doppelter Dateien in Linux

So finden Sie doppelte Dateien in Linux und entfernen sie

Finden Sie Dateien und Verzeichnisse unter Linux ganz einfach

So stellen Sie Datum und Uhrzeit unter Linux ein

Cron-Jobs für Linux einrichten und die 10 besten Online-Tools für Cron-Jobs