2013-05-01 14 views
26

Sono assolutamente alle prime armi in bash, quindi ecco il mio problema:
Qualsiasi numero di righe di testo viene fornito dallo standard input.
Output: numero di righe non ripetute.

Ad esempio:
INPUT:
Righe univoche in bash

Lei indossa scarpe nere.
Mi chiamo Johny.
Odio i lunedì.
Mi chiamo Johny.
Non ti capisco.
Indossa scarpe nere.

USCITA:

risposta

69

Si potrebbe provare a utilizzare uniq man uniq e procedere come segue

sort file | uniq -u | wc -l 
+1

ho aggiunto il comando 'sort' nel mix. Bella presa ... L'ho messa fuori uso – Ding

+13

nelle pagine man che afferma: Nota: 'uniq' non rileva linee ripetute a meno che non siano adiacenti. Potresti voler ordinare prima l'input, o usare 'sort -u 'senza' uniq'. Inoltre, i confronti rispettano le regole specificate da "LC_COLLATE". Ha funzionato anche ... –

7

Ecco come mi piacerebbe risolvere il problema:

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

Ma è piuttosto opaco. Ecco un (leggermente) modo più leggibile di vedere le cose (richiede bash versione 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 
} 
+0

+1: Non so perché qualcuno dovrebbe minimizzare una soluzione funzionante, ma mi piace questo dato che mostra il vero potere della shell (almeno quelli che supportano gli array associativi). –

+0

sulla mia macchina '99 la soluzione di awk ha funzionato senza problemi – sfiore

+0

@sfiore, cos'è una "macchina da 99"? –

Problemi correlati