Domanda

Ho uno script ksh che restituisce un lungo elenco di valori, newline separati, e voglio vedere solo i valori univoci / distinti. È possibile farlo?

Ad esempio, supponiamo che il mio output sia suffissi di file in una directory:

tar
gz
java
gz
java
tar
class
class

Voglio vedere un elenco come:

tar
gz
java
class
È stato utile?

Soluzione

Potresti voler guardare le applicazioni uniq e sort .

./yourscript.ksh | sort | uniq

(Cordiali saluti, sì, l'ordinamento è necessario in questa riga di comando, uniq rimuove solo le linee duplicate che si trovano immediatamente una dopo l'altra)

Modifica

Contrariamente a quanto è stato pubblicato da Aaron Digulla in relazione alle opzioni della riga di comando di uniq :

Dato il seguente input:

class
jar
jar
jar
bin
bin
java

uniq produrrà tutte le righe esattamente una volta:

class
jar
bin
java

uniq -d produrrà tutte le righe che appaiono più di una volta e le stamperà una volta:

jar
bin

uniq -u produrrà tutte le righe che appaiono esattamente una volta e le stamperanno una volta:

class
java

Altri suggerimenti

./script.sh | sort -u

È lo stesso di monoxide's rispondi , ma un po 'più conciso.

Per set di dati più grandi in cui l'ordinamento potrebbe non essere desiderabile, puoi anche utilizzare il seguente script perl:

./yourscript.ksh | perl -ne 'if (!defined $x{

Per set di dati più grandi in cui l'ordinamento potrebbe non essere desiderabile, puoi anche utilizzare il seguente script perl:

<*>

Questo in pratica ricorda solo ogni output di linea in modo che non lo ritorni più.

Ha il vantaggio rispetto all'ordinamento | uniq " soluzione in quanto non è necessario un ordinamento anticipato.

}) { print

Per set di dati più grandi in cui l'ordinamento potrebbe non essere desiderabile, puoi anche utilizzare il seguente script perl:

<*>

Questo in pratica ricorda solo ogni output di linea in modo che non lo ritorni più.

Ha il vantaggio rispetto all'ordinamento | uniq " soluzione in quanto non è necessario un ordinamento anticipato.

; $x{

Per set di dati più grandi in cui l'ordinamento potrebbe non essere desiderabile, puoi anche utilizzare il seguente script perl:

<*>

Questo in pratica ricorda solo ogni output di linea in modo che non lo ritorni più.

Ha il vantaggio rispetto all'ordinamento | uniq " soluzione in quanto non è necessario un ordinamento anticipato.

} = 1; }'

Questo in pratica ricorda solo ogni output di linea in modo che non lo ritorni più.

Ha il vantaggio rispetto all'ordinamento | uniq " soluzione in quanto non è necessario un ordinamento anticipato.

Con zsh puoi farlo:

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

Oppure puoi usare AWK:

zsh-4.3.9[t]% awk '!_[<*>]++' infile    
tar
more than one word
gz
java
class

Instradali attraverso sort e uniq . Questo rimuove tutti i duplicati.

uniq -d fornisce solo i duplicati, uniq -u fornisce solo quelli unici (rimuove i duplicati).

Con AWK puoi farlo, lo trovo più veloce dell'ordinamento

 ./yourscript.ksh | awk '!a[<*>]++'

Unico, come richiesto, (ma non ordinato);
utilizza meno risorse di sistema per meno di ~ 70 elementi (come testato nel tempo);
scritto per ricevere input da stdin,
(o modifica e includi in un altro 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]=\0'
            for ((j=i+1; j < n; j++)); do
                [[ ${a_set[i]} == ${a_bag[j]} ]] && a_bag[j]=\0'
            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[@]}"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top