Sebuah solusi - bukan solusi yang elegan seperti yang mengubah variabel * RS, tapi mungkin cukup jelas:
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`
Seluruh program bekerja di blok BEGIN dan END . Ini menarik variabel PATH Anda dari lingkungan, membaginya menjadi beberapa unit. Ini kemudian beralih di atas p array yang dihasilkan (yang dibuat dalam urutan oleh split()
). Array e adalah array asosiatif yang digunakan untuk menentukan apakah kita telah melihat elemen path saat ini (misalnya / usr / local / bin ) sebelumnya, dan jika tidak, ditambahkan ke np , dengan logika untuk menambahkan titik dua ke np jika sudah ada teks di np . The END blok hanya echos np . Ini dapat lebih disederhanakan dengan menambahkan-F:
menandai, menghapus argumen ketiga ke split()
(karena default ke FS ), dan mengubah np = np ":"
ke np = np FS
, memberi kita:
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
Naif, saya percaya itu for(element in array)
akan menjaga ketertiban, tetapi tidak, jadi solusi asli saya tidak bekerja, karena orang-orang akan marah jika seseorang tiba-tiba mengacak urutan mereka $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