GNU/Linux >> Tutoriels Linux >  >> Linux

Outils Linux pour traiter les fichiers comme des ensembles et effectuer des opérations d'ensemble sur eux ?

Est-ce que quelqu'un connaît un outil Linux spécialement conçu pour traiter les fichiers comme des ensembles et effectuer des opérations d'ensemble sur eux ? Comme la différence, l'intersection, etc ?

Réponse acceptée :

En supposant que les éléments sont des chaînes de caractères autres que NUL et newline (attention, cette nouvelle ligne est cependant valide dans les noms de fichiers), vous pouvez représenter un ensemble sous forme de fichier texte avec un élément par ligne et utilisez certains des utilitaires Unix standard.

Définir l'adhésion

$ 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 }'

Définir l'intersection

$ 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

Définir l'égalité

$ 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

Définir la cardinalité

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

$ awk 'END { print NR }' set

$ sed '$=' set

Test de sous-ensemble

$ 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

Définir l'union

$ 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

Définir le complément

$ 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

Définir la différence symétrique

$ 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

Ensemble de puissance

Tous les sous-ensembles possibles d'un ensemble s'affichent séparés, un par ligne :

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

(en supposant que les éléments ne contiennent pas SPC, TAB (en supposant la valeur par défaut de $IFS ), barre oblique inverse, caractères génériques).

En relation:Quel logiciel de compression de fichiers pour Linux offre la réduction de taille la plus élevée ??

Définir le produit cartésien

$ 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

Test d'ensemble disjoint

$ 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

Test d'ensemble vide

$ 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

Maximum

$ 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

Tous disponibles sur http://www.catonmat.net/blog/set-operations-in-unix-shell-simplified/


Linux
  1. 5 outils de ligne de commande pour trouver rapidement des fichiers sous Linux

  2. Comment archiver et compresser des fichiers sous Linux

  3. Linux – Stocké dans les fichiers /dev/pts et pouvons-nous les ouvrir ?

  4. Linux – Répertoires standard et/ou communs sur les systèmes Unix/linux ?

  5. Linux Supprimer des fichiers et des répertoires

Comment définir et répertorier les variables d'environnement sous Linux

Les 3 meilleurs outils pour rechercher et supprimer des fichiers en double sous Linux

Comment trouver des fichiers en double sous Linux et les supprimer

Trouvez facilement des fichiers et des répertoires sur Linux

Comment définir la date et l'heure sous Linux

Configurer des tâches Cron pour Linux et 10 meilleurs outils en ligne pour les tâches Cron