Sélectionnez des valeurs uniques ou distinctes à partir D'une liste dans le script shell UNIX

j'ai un script ksh qui retourne une longue liste de valeurs, newline séparé, et je veux voir seulement les valeurs uniques/distinctes. Il est possible de faire cela?

par exemple, dire que ma sortie est des suffixes de fichier dans un répertoire:

tar
gz
java
gz
java
tar
class
class

je veux voir une liste comme:

tar
gz
java
class
175
demandé sur brabster 2009-03-06 13:33:38

7 réponses

vous pourriez vouloir regarder les applications uniq et sort .

./yourscript.ksh | sort | uniq

(pour information, oui, le tri est nécessaire dans cette ligne de commande, uniq ne supprime que les lignes en double qui sont immédiatement après l'autre)

EDIT:

contrairement à ce qui a été publié par Aaron Digulla en relation avec uniq 's options de ligne de commande:

étant donné l'entrée suivante:

class
jar
jar
jar
bin
bin
java

uniq produira toutes les lignes exactement une fois:

class
jar
bin
java

uniq -d produira toutes les lignes qui apparaissent plus d'une fois, et il les imprimera une fois:

jar
bin

uniq -u produira toutes les lignes qui apparaissent exactement une fois, et il les imprimera une fois:

class
java
327
répondu Matthew Scharley 2017-05-23 10:31:38
./script.sh | sort -u

C'est la même chose que monoxyde de réponse , mais un peu plus concis.

68
répondu gpojd 2017-05-23 11:47:30

pour les ensembles de données plus grands où le tri peut ne pas être souhaitable, vous pouvez également utiliser le script perl suivant:

./yourscript.ksh | perl -ne 'if (!defined $x{$_}) { print $_; $x{$_} = 1; }'

cela se souvient simplement de chaque sortie de ligne de sorte qu'il ne sort pas à nouveau.

il a l'avantage sur la solution " sort | uniq " en ce qu'il n'y a pas de tri requis à l'avance.

9
répondu paxdiablo 2009-03-06 11:02:43

avec zsh vous pouvez faire ceci:

zsh-5.0.0[t]% cat infile 
tar
more than one word
gz
java
gz
java
tar
class
class
zsh-5.0.0[t]% print -l "${(fu)$(<infile)}"
tar
more than one word
gz
java
class

ou vous pouvez utiliser AWK:

zsh-4.3.9[t]% awk '!_["151910920"]++' infile    
tar
more than one word
gz
java
class
9
répondu Dimitre Radoulov 2014-01-18 17:29:36

Pipe eux par des sort et uniq . Cela supprime tous les doublons.

uniq -d donne seulement les duplicata, uniq -u donne seulement les uniques (bandes duplicata).

9
répondu Aaron Digulla 2015-05-29 11:25:12

Avec AWK vous pouvez le faire, je le trouve plus rapide que le tri

 ./yourscript.ksh | awk '!a["151900920"]++'
6
répondu Ajak6 2017-05-22 21:27:52

Unique, tel que demandé, (mais non trié);

utilise moins de ressources système pour moins de ~ 70 éléments (tel que Testé avec le temps);

écrit pour prendre la contribution de stdin,

(ou modifier et inclure dans un autre script):

(Bash)

bag2set () {
    # Reduce a_bag to a_set.
    local -i i j n=${#a_bag[@]}
    for ((i=0; i < n; i++)); do
        if [[ -n ${a_bag[i]} ]]; then
            a_set[i]=${a_bag[i]}
            a_bag[i]=$'"151900920"'
            for ((j=i+1; j < n; j++)); do
                [[ ${a_set[i]} == ${a_bag[j]} ]] && a_bag[j]=$'"151900920"'
            done
        fi
    done
}
declare -a a_bag=() a_set=()
stdin="$(</dev/stdin)"
declare -i i=0
for e in $stdin; do
    a_bag[i]=$e
    i=$i+1
done
bag2set
echo "${a_set[@]}"
1
répondu FGrose 2012-07-31 03:54:19