GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo usar comodines en un comando xargs?

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

Linux
  1. Cómo usar BusyBox en Linux

  2. Cómo usar los comandos del historial de Bash

  3. Cómo uso cron en Linux

  4. Cómo usar BUSCAR en Linux

  5. Cómo usar el comando Su en Linux

Cómo usar el comando nohup de Linux

Cómo usar traceroute en Kali Linux

Cómo usar Instagram en la terminal

Cómo usar el comando PS

Cómo usar el comando SUPERIOR

Cómo usar FTP