2011-01-14 15 views
21

Estoy intentando conseguir el mismo efecto que escribircómo hacer que bash expanda comodines en variables?

mv ./images/*.{pdf,eps,jpg,svg} ./images/junk/ 

en la línea de comandos, desde el interior de una escritura del golpe. Tengo:

MYDIR="./images" 
OTHERDIR="./images/junk" 
SUFFIXES='{pdf,eps,jpg,svg}' 
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/" 

que, cuando se ejecuta, da el error no es algo inesperado:

mv: rename ./images/*.{pdf,eps,jpg,svg} to ./images/junk/*.{pdf,eps,jpg,svg}: 
No such file or directory 

¿Cuál es la forma correcta de citar todo esto para que mv hará realmente la expansión deseada? (Sí, hay un montón de archivos que coinciden con el patrón en ./images/.)

Respuesta

22

Una respuesta eliminada estaba en el camino correcto. Una ligera modificación en su intento:

shopt -s extglob 
MYDIR="./images" 
OTHERDIR="./images/junk" 
SUFFIXES='@(pdf|eps|jpg|svg)' 
mv "$MYDIR/"*.$SUFFIXES "$OTHERDIR/" 

expansión de llaves se realiza antes de la expansión de variables, pero la expansión de variables se realiza antes de la expansión ruta. Entonces, las llaves siguen siendo llaves cuando la variable se expande en su original, pero cuando la variable contiene elementos de nombre de ruta, ya se han expandido cuando se realiza la expansión de la ruta de acceso.

+3

+1, buen truco, no sabía nada de '@()', aprendí algo nuevo. Solo busqué en la página de manualidades, para cualquiera que se pregunte si hay ''() 'patrones,' *() 'patrones,' +() 'patrones,' @() 'patrones y'!() 'Patrones. Todo disponible si 'extglob' está habilitado. – falstro

+0

Brillante, gracias! Citar y expandir en scripts de shell siempre me causa problemas, esto ayudará mucho. –

+1

@RossDuncan, sugiero http://mywiki.wooledge.org/BashParser como un lugar para comenzar para obtener una buena referencia sobre las fases involucradas en el modelo de ejecución del intérprete de órdenes y sobre el orden en que ocurren. –

5

Tendrá que eval esa línea con el fin de que funcione, así:

MYDIR="./images" 
OTHERDIR="./images/junk" 
SUFFIXES='{pdf,eps,jpg,svg}' 
eval "mv \"$MYDIR\"/*.$SUFFIXES \"$OTHERDIR/\"" 

Ahora, esto tiene problemas , en particular, si no confía en $SUFFIXES, puede contener un ataque de inyección, pero para este caso simple debería estar bien.

Si está abierto a otras soluciones, es posible que desee experimentar con find y xargs.

+1

+1 para las advertencias. 'eval' es malo. – l0b0

Cuestiones relacionadas