lista de archivos numerados en un rango específico

16

Tengo un conjunto de archivos en un directorio numerado de la siguiente manera:

file1.txt
file2.txt
...
file30.txt
...

Ahora, me gustaría ejecutar un comando en un rango específico de archivos, digamos 18 a 31.

Hasta ahora he usado las siguientes formas,

tres argumentos

command file1[8-9].txt file2[0-9].txt file3[0-1].txt

Ahora supongamos que quiero cualquier otro número,

lazo

for i in `jot - 18 31 2`; do echo file${i}.txt; done | xargs command

Parece que es un bucle más confiable (los espacios funcionan)

for i in `jot - 18 31 2`; do echo "\"file${i}.txt\" "; done | xargs command

pero parece que debería haber una manera más simple de hacer esto. Supongo que la mejor solución es crear una función bash que devolverá el conjunto de archivos a la línea de comandos. Entonces podría hacer algo como,

command `filerange file 18 31`

¿Hay mejores formas o sugerencias para hacerlo de manera eficiente?

Pido disculpas por adelantado si me perdí esta misma pregunta respondida en otro lugar en la web o en superuser.

milkypostman
fuente
Actualicé mi pregunta para incluir una solución usando un forbucle que permita espacios en los nombres de archivo usando xargs. Parece que funciona si no tienes bash 4. Si tienes bash 4, ¡definitivamente usa expansión de llaves! Ver la respuesta seleccionada. Plug desvergonzado para actualizar Snow Leopard bash
milkypostman

Respuestas:

25

Prueba esto:

for file in file{18..31}.txt

Se conoce como una "expresión de secuencia" y es parte de la función de expansión de llaves de Bash . Funciona en Bash 3 y 4.

La función de incremento es nueva para Bash 4. Probablemente tenga Bash 3.x.

En Bash 4, puedes hacer:

$ for i in {1..6..2}; do echo $i; done
1
3
5

Pero en Bash 3, debes hacer esto para obtener los mismos resultados:

$ for ((i=1; i<=6; i+=2)); do echo $i; done

La misma forma que se incrementa en uno:

$ for ((i=1; i<=6; i++)); do echo $i; done

Cualquiera de los números pueden ser variables o expresiones. Sin embargo, en una expresión de secuencia, los números tienen que ser constantes

Aquí hay un ejemplo usando ese formulario en sus archivos:

for ((i=18; i<=31; i++))
do
    echo "file${i}.txt"
done

Otra nueva característica de las expresiones de secuencia en Bash 4 es la capacidad de incluir ceros a la izquierda. Esto es útil si desea crear (y usar) archivos numerados que puedan ordenarse correctamente.

En Bash 4:

touch file{001..010}.txt

crearía archivos llamados "file001.txt" a través de "file010.txt". Sus nombres se ordenarán en el orden esperado. Sin los ceros a la izquierda, "file10.txt" se ordenaría antes de "file1.txt".

Para trabajar con los archivos, puede usar la misma sintaxis cero inicial:

for file in file{001..010}.txt; do echo "$file"; done

En Bash 3, si necesita ceros a la izquierda, debe rellenar el valor usted mismo:

for i in {1..10}
do
    printf -v i '%03d' $i 
    echo "file${i}.txt"
done

los printf declaración antepondrá el valor de i con ceros a la izquierda para que el ancho sea 3, por ejemplo ("4" se convierte en "004").

Editar:

Acomodar espacios en los nombres de archivo es sencillo:

$ touch "space name "{008..018..3}" more spaces"
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces
$ for f in "space name "{008..018..3}" more spaces"; do mv "$f" "${f}.txt"; done
$ ls -l sp*
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000008 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000011 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000014 more spaces.txt
-rw-r--r-- 1 user group 0 2011-01-22 11:48 space name 000017 more spaces.txt
Pausado hasta nuevo aviso.
fuente
¡Gracias! No sé dónde ha estado toda mi vida. Sin embargo, lo único que no puedo hacer para trabajar es que el incremento no parece funcionar en la versión OSX de bash. es decir, no puedo ponerme {1..10..2}a trabajar en mi OSX bash.
milkypostman
Bueno, es porque Snow Leopard (por alguna razón) está usando bash 3.1. Este es un problema de software.
milkypostman
@milkypostman: La función de incremento y los ceros iniciales {01..10}son nuevos en Bash 4. Probablemente tenga Bash 3.x. Si necesita la función de incremento o para usar variables para los límites del rango, entonces use este formulario: for ((i=1; i<=10; i+=2}(o i++para incrementar en uno). Cualquiera de los números pueden ser variables o expresiones. Luego, para usar el valor dentro del forciclo: echo "file${i}.txt". In Bash 3, if you need leading zeros, inside the for loop do: printf -vi '% 03d' $ i` que antepondrá el valor de iceros a la izquierda para que el ancho sea 3, por ejemplo ("4" se convierte en "004").
Pausado hasta nuevo aviso.
Dennis, ¿hay alguna forma de actualizar su solución para incluir el formulario alternativo? Siendo un comentario, ofusca un poco lo que probablemente se supone que debo obtener.
milkypostman
@milkypostman: Vea mi respuesta editada.
Pausado hasta nuevo aviso.