Ist es möglich, einen Verzeichniseintrag zu „partitionieren“ – sagen wir in Blöcke mit einer bestimmten Anzahl, um verschiedene Aktionen für jeden „Bereich“ durchzuführen?
Nehmen wir zum Beispiel an, ich habe die folgenden Verzeichnisse in einem anderen Ordner:
$ ls test
abc/
def/
hij/
klm/
nop/
qrs/
tuv/
wxy/
zzz/
Und ich möchte eine Aktion für die ersten 3 Verzeichnisse ausführen, eine andere für die zweiten 3 und so weiter.
Mein Gedanke war, dass vielleicht eine Schleife über Zahlen funktionieren würde, basierend auf der Ausgabe von so etwas wie ls | nl
(aber bevor es jemand erwähnt, ich weiß, wie man ls
analysiert geht nicht!)
Das funktioniert offensichtlich nicht, verdeutlicht aber, wie ich hoffe, meinen Punkt:
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
Die Ordner, mit denen ich das tatsächlich machen möchte, können in beliebiger Reihenfolge bearbeitet werden (d. h. die endgültige Aufteilung kann völlig willkürlich sein), aber sie haben keine logische Namenskonsistenz – was bedeutet, dass sie nicht sinnvoll alphabetisch oder numerisch organisiert werden können basierend auf einem beliebigen Schlüssel innerhalb des Verzeichnisnamens selbst.
Akzeptierte Antwort:
Es gibt keinen Grund, einen der folgenden Fehler zu begehen für diese Situation:
- Verwenden Sie nicht-portable GNU-Erweiterungen (wie
xargs -0
) - Parsen Sie die Dateinamen nur als Textstrom und geben Sie vor, dass sie keine Zeilenumbrüche enthalten können.
Sie können dies ohne große Schwierigkeiten portabel handhaben:
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
Das ist wirklich ausführlicher als nötig, aber so ist es lesbar.
Für eine andere Art der Partitionierung, bei der Sie alle Verzeichnisse in genau drei verschiedene Behandlungsmethoden aufteilen möchten (aber nicht gleichzeitig behandeln müssen), könnten Sie es so machen:
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