Est-il possible de "partitionner" une liste de répertoires - par exemple en blocs d'un certain nombre, pour effectuer différentes actions sur chaque "plage" ?
Par exemple, disons que j'ai les répertoires suivants dans un autre dossier :
$ ls test
abc/
def/
hij/
klm/
nop/
qrs/
tuv/
wxy/
zzz/
Et je veux effectuer une action sur les 3 premiers répertoires, une autre sur les 3 seconds, et ainsi de suite.
Ma pensée était que peut-être une boucle à travers les nombres fonctionnerait, basée sur la sortie de quelque chose comme ls | nl
(mais avant que quelqu'un ne le mentionne, je sais analyser ls
est un non-non !)
Cela ne fonctionne évidemment pas, mais illustre mon propos j'espère :
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
Les dossiers sur lesquels j'ai l'intention de faire cela peuvent être travaillés dans n'importe quel ordre (c'est-à-dire que les divisions finales peuvent être totalement arbitraires), mais ils n'ont aucune cohérence de nommage logique - ce qui signifie qu'ils ne peuvent pas être organisés de manière alphabétique ou numérique. basé sur n'importe quelle clé dans le nom du répertoire lui-même.
Réponse acceptée :
Il n'y a aucune raison de faire l'une des erreurs suivantes pour cette situation :
- Utilisez des extensions GNU non portables (telles que
xargs -0
) - Analyser les noms de fichiers comme un flux de texte uniquement, en prétendant qu'ils ne peuvent pas contenir de nouvelles lignes.
Vous pouvez gérer cela de manière portable sans trop de difficulté :
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
Vraiment, c'est plus verbeux que nécessaire, mais c'est lisible de cette façon.
Pour un autre type de partitionnement, où vous souhaitez diviser tous les répertoires en exactement trois méthodes de gestion différentes (mais n'avez pas besoin de les gérer en même temps), vous pouvez procéder ainsi :
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