¿Es posible 'particionar' una lista de directorios, digamos en bloques de algún número, para realizar diferentes acciones en cada 'rango'?
Por ejemplo, digamos que tengo los siguientes directorios dentro de otra carpeta:
$ ls test
abc/
def/
hij/
klm/
nop/
qrs/
tuv/
wxy/
zzz/
Y quiero realizar alguna acción en los primeros 3 directorios, otra en los segundos 3, y así sucesivamente.
Pensé que tal vez funcionaría un ciclo entre números, basado en la salida de algo como ls | nl
(pero antes de que alguien lo mencione, sé analizar ls
es un no-no!)
Obviamente, esto no funciona, pero espero que ilustre mi punto:
for dir in `ls | nl`;
do
do-something-with ${dir{1..3}} # Where $dir has taken on some numerical value linked to the folder)
do-something-with ${dir{4..6}}
# And so on...
do-something-with ${dir{n-3..n}}
done
Las carpetas en las que tengo la intención de hacer esto, se pueden trabajar en cualquier orden (es decir, las divisiones finales pueden ser totalmente arbitrarias), pero no tienen una consistencia de nomenclatura lógica, lo que significa que no se pueden organizar alfabética o numéricamente con sensatez. basado en cualquier clave dentro del nombre del directorio.
Respuesta aceptada:
No hay motivo para cometer ninguno de los siguientes errores para esta situación:
- Utilice extensiones GNU no portátiles (como
xargs -0
) - Analice los nombres de archivo como una secuencia de texto únicamente, fingiendo que no pueden contener saltos de línea.
Puede manejar esto de forma portátil sin mucha dificultad:
set -- */
while [ "$#" -gt 0 ]; do
case "$#" in
1)
my-command "$1"
shift 1
;;
2)
my-command "$1" "$2"
shift 2
;;
*)
my-command "$1" "$2" "$3"
shift 3
;;
esac
done
Realmente esto es más detallado de lo necesario, pero se puede leer de esta manera.
Para un tipo diferente de partición, donde desea dividir todos los directorios en exactamente tres métodos diferentes de manejo (pero no necesita manejarlos al mismo tiempo), puede hacerlo así:
x=1
for d in *; do
[ ! -d "$d" ] && continue
case "$x" in
1)
# do stuff with "$d"
;;
2)
# do stuff with "$d"
;;
3)
# do stuff with "$d"
;;
esac
x=$(($x+1))
[ "$x" -eq 4 ] && x=1
done