Una soluzione - non elegante quanto quelle che cambiano le variabili * RS, ma forse ragionevolmente chiara:
PATH=`awk 'BEGIN {np="";split(ENVIRON["PATH"],p,":"); for(x=0;x<length(p);x++) { pe=p[x]; if(e[pe] != "") continue; e[pe] = pe; if(np != "") np=np ":"; np=np pe}} END { print np }' /dev/null`
L'intero programma funziona nei blocchi BEGIN ed END . Estrae la variabile PATH dall'ambiente, suddividendola in unità. Quindi scorre sull'array risultante p (che viene creato in ordine di split()
). L'array e è un array associativo che viene utilizzato per determinare se abbiamo già visto l'elemento del percorso corrente (ad es. / Usr / local / bin ) e, in caso contrario, è aggiunto a np , con la logica per aggiungere un colon a np se c'è già del testo in np . Il blocco END semplicemente echos np . Ciò potrebbe essere ulteriormente semplificato aggiungendo il-F:
flag, eliminando il terzo argomento in split()
(come predefinito in FS ) e cambiando np = np ":"
in np = np FS
, dandoci:
awk -F: 'BEGIN {np="";split(ENVIRON["PATH"],p); for(x=0;x<length(p);x++) { pe=p[x]; if(e[pe] != "") continue; e[pe] = pe; if(np != "") np=np FS; np=np pe}} END { print np }' /dev/null
Incredibilmente, credevo che for(element in array)
avrebbe preservato l'ordine, ma non funziona, quindi la mia soluzione originale non funziona, dato che la gente si arrabbierebbe se qualcuno improvvisamente decifrasse l'ordine del loro $PATH
:
awk 'BEGIN {np="";split(ENVIRON["PATH"],p,":"); for(x in p) { pe=p[x]; if(e[pe] != "") continue; e[pe] = pe; if(np != "") np=np ":"; np=np pe}} END { print np }' /dev/null