Impara a usare il comando uniq in Unix e Linux con questi esempi pratici.
Il comando uniq in Unix e Linux viene utilizzato per filtrare il testo duplicato. Può essere usato da solo ma è comunemente usato insieme ad altri comandi come identificare le informazioni ridondanti in un file.
Ecco la sintassi del comando uniq:
uniq [options] <input-file> <output-file>
Quando esegui uniq senza opzioni, utilizzerà stdin e stdout per input e output.
Sebbene l'utilizzo di stdin sia possibile utilizzando gli appunti (copia/incolla), questo non è l'uso più pratico.
Invece probabilmente vorresti usare questo comando su un file che sospetti contenga informazioni duplicate.
Una limitazione del comando uniq è che identificherà solo i duplicati adiacenti o uno accanto all'altro nel file. Questo è piuttosto semplice, ma lascia che te lo mostri in un esempio in modo che tu possa vederlo in azione.
[[email protected] ~]$ cat apple.txt
apple
apple
orange
orange
apple
orange
[[email protected] ~]$ uniq apple.txt
apple
orange
apple
orange
Quindi, sai subito che non puoi fidarti del programma per identificare ogni duplicato da solo. Ci sono alcuni modi per aggirare questo problema e normalmente è con il comando sort.
Te lo mostrerò più avanti in questo articolo. Per prima cosa, permettetemi di scorrere alcuni esempi per familiarizzare con "uniq" prima di aggiungere altri comandi e cose potenzialmente confuse.
7 esempi del comando uniq in Linux
Ho usato un vero registro di sistema ma l'ho modificato a scopo dimostrativo. La maggior parte del file è già stata ordinata in ordine adiacente, ma ho lasciato un paio di righe "fuori posto" per mostrare la funzionalità del comando uniq.
https://gist.github.com/abhishekpc/7dada8c6e57fd5b854f9d2dae72dddb0DOWNLOAD FILE DI TESTO DI ESEMPIO
Esempio 1:utilizzo del comando uniq nel modo predefinito
Anche se te l'ho già mostrato, diamo un'occhiata al nostro file di esempio usando la sintassi predefinita.
[[email protected] ~]$ uniq sample_log_file.txt
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device is a keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device removed
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0
/usr/lib/gdm3/gdm-x-session[1443]: (II) This device may have been added with another device file.
PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
Puoi vedere che molte delle righe duplicate sono consolidate, ma contiene ancora informazioni ridondanti. Ciò è dovuto alla limitazione funzionale che ho già descritto. Diamo un'occhiata ad alcuni altri esempi ed esaminiamo alcune delle opzioni integrate nell'utilità della riga di comando "uniq".
Esempio 2:invia i risultati filtrati al file di destinazione
Potresti voler salvare questo output in modo da poterlo facilmente modificare o preservare. Puoi indirizzare il nostro output su un file separato invece del normale stdout (terminale). È importante notare che non è possibile utilizzare questo formato per sovrascrivere il file originale.
[[email protected] ~]$ uniq sample_log_file.txt uniq_log_output.txt
Ecco il contenuto del file di output:
[[email protected] ~]$ cat uniq_log_output.txt
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device is a keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device removed
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0
/usr/lib/gdm3/gdm-x-session[1443]: (II) This device may have been added with another device file.
PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
Esempio 3:utilizzo di '-c' per ottenere il conteggio delle righe ripetute
Questa opzione è abbastanza autoesplicativa. Il programma aggiungerà il conteggio all'inizio di ogni riga.
[[email protected] ~]$ uniq sample_log_file.txt -c
2 /usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
2 /usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device is a keyboard
1 /usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device removed
2 /usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard
5 /usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
1 /usr/lib/gdm3/gdm-x-session[1443]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0
7 /usr/lib/gdm3/gdm-x-session[1443]: (II) This device may have been added with another device file.
1 PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
8 wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
Esempio 4:stampa solo righe ripetute con '-d'
Come puoi vedere, vengono mostrate solo le righe che sono duplicate nel file, se usi l'opzione -d del comando uniq.
[[email protected] ~]$ uniq sample_log_file.txt -d
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device is a keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: is tagged by udev as: Keyboard
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
/usr/lib/gdm3/gdm-x-session[1443]: (II) This device may have been added with another device file.
wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
Esempio 5:stampa solo righe univoche con '-u'
Qui ottieni l'output inverso del comando precedente. Nessuno di questi comandi viene ripetuto nel file.
[[email protected] ~]$ uniq sample_log_file.txt -u
/usr/lib/gdm3/gdm-x-session[1443]: (II) event9 - Intel HID events: device removed
/usr/lib/gdm3/gdm-x-session[1443]: (II) systemd-logind: got fd for /dev/input/event10 13:74 fd 55 paused 0
PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
Esempio 6:ignora campi o caratteri con uniq ['-f' e '-s']
Questi sono davvero due esempi, ma le funzioni sono quasi identiche. Spiegherò come funzionano e poi fornirò un po' di chiarezza sulle differenze tra i due.
Ognuno di loro usa la seguente sintassi
Skip fields with:
uniq <source_file> -f N
Skip characters with:
uniq <source_file> -s N
In ciascuno di questi esempi, 'N' è il conteggio degli elementi che desideri saltare. Quando salti questo numero di elementi, uniq inizierà il confronto da quel punto anziché confrontare l'intera riga.
L'opzione 'f' salterà il numero di campi assegnato. I campi verranno interpretati utilizzando lo spazio vuoto.
[[email protected] ~]$ cat field_separated_values.txt
blue fish
blue fish
blue fish
blue class
red fish
green fish
two class
two class
Se vuoi usare il comando uniq sulla seconda colonna, dovrai saltare il primo campo in questo modo:
[[email protected] ~]$ uniq -f1 field_separated_values.txt
blue fish
blue class
red fish
two class
Come puoi vedere, prende sia "pesce rosso" che "pesce verde" come la stessa linea perché il primo campo (con i colori) è stato ignorato. Se utilizzi l'opzione di conteggio qui, ti mostrerà il conteggio delle linee univoche che ha trovato:
[[email protected] ~]$ uniq -f1 -c field_separated_values.txt
3 blue fish
1 blue class
2 red fish
2 two class
Perché dovresti averne bisogno? Ti darò uno scenario pratico. Molti file di registro hanno il timestamp all'inizio delle righe. Se stai cercando di trovare solo le righe univoche in un file di questo tipo, puoi saltare il primo campo con il timestamp con l'opzione -f.
Allo stesso modo puoi saltare un numero specifico di caratteri.
[[email protected] ~]$ uniq -s 10 field_separated_values.txt
blue fish
Esempio 7:usa '-w' per confrontare solo N caratteri
L'opzione '-w' ci consente di specificare un numero esatto di caratteri da utilizzare nel nostro confronto.
Se hai usato il file di registro per gli esempi delle coppie precedenti, va bene. Volevo rendere il testo di confronto un po' più semplice per limitare la confusione. In caso contrario, riprendiamolo e vediamo cosa succede quando usi solo il primo per i personaggi per trovare i duplicati.
[[email protected] ~]$ uniq -w 4 sample_log_file.txt
/usr/lib/gdm3/gdm-x-session[1443]: (II) No input driver specified, ignoring this device.
PackageKit: get-updates transaction /354_eebeebaa from uid 1000 finished with success after 1514ms
wpa_supplicant[898]: RRM: Ignoring radio measurement request: Not RRM network
Tutte le righe che iniziano con "/usr" sono ora identificate come "stesse" dal punto di vista del programma.
Questo potrebbe rivelarsi utile se stai cercando un evento di registro particolare.
Bonus:evita corrispondenze incomplete usando 'sort' e 'uniq' contemporaneamente.
Puoi eseguire questi comandi separatamente per ottenere lo stesso effetto, ma se non hai mai usato una pipe (il carattere |) in Linux, questo è un ottimo modo per conoscerli.
Puoi utilizzare le pipe per combinare diversi comandi per salvarci le sequenze di tasti e migliorare il nostro flusso di lavoro. I comandi verranno eseguiti nell'ordine in cui sono stati digitati.
Questo è l'input di esempio che userò:
[[email protected] ~]$ cat apple.txt
apple
orange
orange
apple
apple
banana
apple
banana
Ora, ordiniamo il file di input e quindi utilizziamo il comando uniq su di esso. Il comando di ordinamento riordina il testo in modo che tutti gli elementi siano prima nell'ordine adiacente. Quindi, quando viene eseguito il comando uniq, trova solo 3 righe univoche nel file.
[[email protected] ~]$ sort apple.txt | uniq
apple
banana
orange
Se inverti l'ordine, le cose cambieranno. Eseguendo prima il comando 'uniq' verranno identificati solo i duplicati adiacenti, quindi ciascuno di essi verrà ordinato in ordine alfabetico utilizzando il comando 'sort'.
[[email protected] ~]$ uniq apple.txt | sort
apple
apple
apple
banana
banana
orange
Le pipe ci consentono di eseguire più comandi contemporaneamente, ma è importante considerare il loro ordine.
Si noti che il contenuto del file rimane invariato proprio come farebbe quando si eseguono i comandi singolarmente. Il collegamento dei due comandi insieme mantiene anche i risultati nella "memoria" del sistema. Se li esegui separatamente, non potresti ottenere questi risultati a meno che tu non abbia creato un nuovo file e lo abbia utilizzato per sovrascrivere il contenuto dell'originale prima di eseguire il secondo comando.
Conclusione
Come puoi immaginare, questo rende questo un concetto importante nell'apprendimento di bash. Questi comandi particolari (sort e uniq) vengono spesso usati insieme per filtrare rapidamente le informazioni da file di grandi dimensioni come il nostro pseudo-log.