È possibile "partizionare" un elenco di directory, ad esempio blocchi di un certo numero, per eseguire azioni diverse su ciascun "intervallo"?
Ad esempio, supponiamo di avere le seguenti directory all'interno di un'altra cartella:
$ ls test
abc/
def/
hij/
klm/
nop/
qrs/
tuv/
wxy/
zzz/
E voglio eseguire alcune azioni sulle prime 3 directory, un'altra sulle seconde 3 e così via.
Il mio pensiero era che forse un ciclo tra i numeri avrebbe funzionato, in base all'output di qualcosa come ls | nl
(ma prima che qualcuno lo menzioni, so analizzare ls
è un no-no!)
Questo ovviamente non funziona, ma spero che illustra il mio 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
Le cartelle su cui intendo effettivamente farlo, possono essere lavorate in qualsiasi ordine (cioè le divisioni finali possono essere totalmente arbitrarie), ma non hanno coerenza logica di denominazione, con ciò intendo dire che non possono essere organizzate in modo sensato alfabetico o numerico in base a qualsiasi chiave all'interno del nome della directory stessa.
Risposta accettata:
Non c'è motivo di fare nessuno dei seguenti errori per questa situazione:
- Usa estensioni GNU non portatili (come
xargs -0
) - Analizza i nomi dei file solo come flusso di testo, fingendo che non possano contenere nuove righe.
Puoi gestirlo in modo portatile senza troppe difficoltà:
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
In realtà questo è più dettagliato del necessario, ma è leggibile in questo modo.
Per un diverso tipo di partizionamento, in cui vuoi dividere tutte le directory esattamente in tre diversi metodi di gestione (ma non è necessario gestirli contemporaneamente), puoi farlo in questo modo:
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