Pergunta

Eu tenho um script ksh que retorna uma longa lista de valores, de nova linha separada, e eu quero ver apenas os valores exclusivos / distintos. É possível fazer isso?

Por exemplo, digamos que a minha saída é sufixos de arquivo em um diretório:

tar
gz
java
gz
java
tar
class
class

Eu quero ver uma lista como:

tar
gz
java
class
Foi útil?

Solução

Você pode querer olhar para as aplicações uniq e sort.

./yourscript.ksh | sort | uniq

(FYI, sim, o tipo é necessário nesta linha de comando, uniq única tiras linhas duplicadas que estão imediatamente após o outro)

EDIT:

Ao contrário do que foi postado por Aaron Digulla em relação às opções de linha de comando do uniq:

Dada a seguinte entrada:

class
jar
jar
jar
bin
bin
java

saída uniq vontade todas as linhas exatamente uma vez:

class
jar
bin
java

saída uniq -d vontade todas as linhas que aparecem mais de uma vez, e vai imprimi-los uma vez:

jar
bin

saída uniq -u vontade todas as linhas que aparecem somente uma vez, e vai imprimi-los uma vez:

class
java

Outras dicas

./script.sh | sort -u

Este é o mesmo que monóxido é resposta , mas um pouco mais conciso.

Para conjuntos de dados maiores, onde a classificação pode não ser desejável, você também pode usar o seguinte script perl:

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

Isso basicamente apenas se lembra de cada saída de linha para que ele não saída-lo novamente.

Tem a vantagem sobre a solução "sort | uniq" em que não há nenhuma ordenação necessário na frente.

Com zsh você pode fazer isso:

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 você pode usar AWK:

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

Tubo-los através sort e uniq. Isso remove todas as duplicatas.

uniq -d dá apenas as duplicatas, uniq -u dá apenas os únicos (tiras duplicatas).

Com AWK que você pode fazer, acho que é mais rápido do que sort

 ./yourscript.ksh | awk '!a[$0]++'

Original, conforme solicitado, (mas não classificadas);
utilizações menos recursos do sistema para menos de 70 ~ elementos (como testado com o tempo);
escrito para receber a entrada de stdin,
(Ou modificar e incluir em outro 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[@]}"
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top