Rozwiązanie - nie takie eleganckie jak te, które zmieniają zmienne * RS, ale być może dość jasne:
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`
Cały program działa w blokach BEGIN i END . Wyciąga zmienną PATH ze środowiska, dzieląc ją na jednostki. Następnie iteruje się nad wynikową tablicą p (utworzoną w kolejności według split()
). Tablica e jest tablicą asocjacyjną, która jest używana do ustalenia, czy widzieliśmy bieżący element ścieżki (np. / Usr / local / bin ) przed, a jeśli nie, jest dołączany do np. Z logiką, aby dołączyć dwukropek do np, jeśli jest już tekst w np . END blok prostu Echos NP . Można to dodatkowo uprościć, dodając-F:
flagę, eliminując trzeci argument split()
(domyślnie FS ), i zmieniając np = np ":"
na np = np FS
, dając nam:
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
Naiwnie wierzyłem, for(element in array)
że zachowałoby to porządek, ale nie działa, więc moje oryginalne rozwiązanie nie działa, ponieważ ludzie byliby zdenerwowani, gdyby ktoś nagle zakodował swoją kolejność $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