Una solución, no tan elegante como las que cambian las variables * RS, pero quizás razonablemente clara:
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`
Todo el programa funciona en los bloques BEGIN y END . Extrae su variable PATH del entorno, dividiéndola en unidades. Luego itera sobre la matriz resultante p (que se crea en orden por split()
). La matriz e es una matriz asociativa que se usa para determinar si hemos visto o no el elemento de ruta actual (por ejemplo, / usr / local / bin ) y, si no, se agrega a np , con lógica para agregar dos puntos a np si ya hay texto en np . El bloque END simplemente echos np . Esto podría simplificarse aún más agregando el-F:
flag, eliminando el tercer argumento para split()
(como el valor predeterminado es FS ), y cambiando np = np ":"
a np = np FS
, dándonos:
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
Ingenuamente, creía que eso for(element in array)
preservaría el orden, pero no lo hace, por lo que mi solución original no funciona, ya que la gente se molestaría si alguien de repente revuelve el orden de sus $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