it-swarm.com.de

Eindeutige Zeilen in Bash

Ich bin ein absoluter Anfänger in Sachen Bash, also hier ist mein Problem:
Bei der Standardeingabe wird eine beliebige Anzahl von Textzeilen angegeben.
Ausgabe: Anzahl der sich nicht wiederholenden Zeilen.

Beispielsweise:
EINGANG:

Sie trägt schwarze Schuhe.
Ich heiße Johny.
Ich hasse Montage.
Ich heiße Johny.
Ich verstehe dich nicht.
Sie trägt schwarze Schuhe.

AUSGABE:

2

45
john blackwood

Sie könnten versuchen, mit uniq man uniq und mache folgendes

sort file | uniq -u | wc -l
104
Ding

So löse ich das Problem:

... | awk '{n[$0]++} END {for (line in n) if (n[line]==1) num++; print num}'

Aber das ist ziemlich undurchsichtig. Hier ist eine (leicht) lesbarere Sichtweise (erfordert Bash-Version 4)

... | {
    declare -A count    # count is an associative array

    # iterate over each line of the input
    # accumulate the number of times we've seen this line
    #
    # the construct "IFS= read -r line" ensures we capture the line exactly

    while IFS= read -r line; do
        (( count["$line"]++ ))
    done

    # now add up the number of lines who's count is only 1        
    num=0
    for c in "${count[@]}"; do
        if (( $c == 1 )); then
            (( num++ ))
        fi
    done

    echo $num
}
8
glenn jackman