O de manera más general, ¿cómo elimino un elemento de una lista separada por dos puntos en una variable de entorno Bash?
Pensé que había visto una forma sencilla de hacer esto hace años, utilizando las formas más avanzadas de expansión variable Bash, pero si es así, lo he perdido. Una búsqueda rápida en Google arrojó sorprendentemente pocos resultados relevantes y ninguno que yo llamaría "simple" o "elegante". Por ejemplo, dos métodos que usan sed y awk, respectivamente:
PATH=$(echo $PATH | sed -e 's;:\?/home/user/bin;;' -e 's;/home/user/bin:\?;;')
PATH=!(awk -F: '{for(i=1;i<=NF;i++){if(!($i in a)){a[$i];printf s$i;s=":"}}}'<<<$PATH)
¿No existe nada sencillo? ¿Hay algo análogo a una función split () en Bash?
Actualización:
Parece que necesito disculparme por mi pregunta intencionalmente vaga; Estaba menos interesado en resolver un caso de uso específico que en provocar una buena discusión. ¡Afortunadamente lo conseguí!
Aquí hay algunas técnicas muy inteligentes. Al final, agregué las siguientes tres funciones a mi caja de herramientas. La magia ocurre en path_remove, que se basa en gran medida en el uso inteligente de awk
la variable RS de Martin York .
path_append () { path_remove $1; export PATH="$PATH:$1"; }
path_prepend () { path_remove $1; export PATH="$1:$PATH"; }
path_remove () { export PATH=`echo -n $PATH | awk -v RS=: -v ORS=: '$0 != "'$1'"' | sed 's/:$//'`; }
El único problema real que hay es el uso de sed
para eliminar el colon posterior. Sin embargo, teniendo en cuenta lo sencillo que es el resto de la solución de Martin, ¡estoy bastante dispuesto a vivir con ella!
Pregunta relacionada: ¿Cómo manipulo los elementos $ PATH en los scripts de shell?
WORK=`echo -n ${1} | awk -v RS=: -v ORS=: '$0 != "'${3}'"' | sed 's/:$//'`; eval "export ${2}=${WORK}"
pero debe llamarlo comofunc $VAR VAR pattern
(basado en @ martin-york y @ andrew-aylett)