Estuviste muy cerca.
seq 15 -1 1 | xargs [email protected] sh -c 'mv @_* @'
Necesita retrasar la interpretación (expansión) del *
hasta después del @
se ha producido la sustitución. (Pero ya entendiste que ese era el problema, ¿verdad?)
Me han aconsejado que nunca inserte un nombre de archivo desconocido (u otra cadena de sustitución) directamente en una línea de comando de shell. El ejemplo anterior probablemente sea bastante seguro, porque sabe cuáles serán las cadenas:15
, 14
, …, 3
, 2
y 1
. Pero usar el ejemplo anterior como plantilla para comandos más complejos puede ser peligroso. Un arreglo más seguro sería
seq 15 -1 1 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @
donde x-sh
es una cadena semi-arbitraria que se usará para etiquetar cualquier mensaje de error emitido por el shell invocado. Esto es equivalente a mi primer ejemplo, excepto que, en lugar de incrustar las cadenas (representadas por @
)directamente en el comando de shell, los inyecta proporcionando el @
como un argumento para el shell, y luego hacer referencia a ellos como "$1"
.
PD Usted sugirió ejecutar el seq
comando en reversa(seq 15 -1 1
, que genera 15
, 14
, …, 3
, 2
, 1
en lugar de 1
, 2
, 3
, …, 14
, 15
) y nadie lo mencionó. Esta sería una parte importante de la respuesta si sus nombres de archivo fueran como 1foo.txt
, 2bar.asc
y 13test.png
, etc. (con varios caracteres que aparecen después del número, en lugar de siempre _
). En ese caso, el comando sería mv "$1"* "$1"
(sin el _
) y, si hiciste 1
primero, luego el comando mv 1* 1
barrería todo el 10quick*
, 11brown*
, 12fox*
, etc., archivos, junto con el 1foo*
archivos Pero
seq 1 15 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @
debe ser seguro.
P.P.D. El seq
POSIX no especifica el comando. Tampoco lo es la expansión de la abrazadera en el caparazón. Se puede construir una solución compatible con POSIX combinando la respuesta de grawity a esta pregunta con esta otra respuesta de Adam Katz:
i=1
while [ "$i" -le 15 ]
do
mv -- "${i}"_* "$i"
i=$((i+1))
done
P.P.P.S. No es crítico cuando sabe que los nombres de archivo comienzan con caracteres alfanuméricos (es decir, letras y dígitos), pero, en casos más generales, debe usar --
entre el nombre del comando y los argumentos. Esto mejora el manejo de los nombres de archivo que comienzan con un guión. El --
le dice al comando que trate el argumento (el nombre del archivo)como un argumento. Sin él, dicho argumento podría tratarse como una cadena de opciones.
Simplemente no uses xargs
para eso. Usa un for
bucle:
for i in $(seq 1 15); do
mv ${i}_* $i
done
Aún mejor es usar la expansión de llaves en lugar de seq
:
mkdir {1..15}
for i in {1..15}; do
mv ${i}_* $i
done