Eine Möglichkeit, es zu tun ist, einfach Schleife über alle Verzeichnisse, die Sie bereits haben, und in jedem Unterverzeichnis der untersten Ebene erstellen das neue Unterverzeichnis und verschieben Sie die Dateien:
for d in ?/?/?/; do (
cd "$d" &&
printf '%.4s\0' * | uniq -z |
xargs -0 bash -c 'for prefix do
s=${prefix:3:1}
mkdir -p "$s" && mv "$prefix"* "$s"
done' _
) done
, die wahrscheinlich ein bisschen braucht Erläuterung.
Der Glob ?/?/?/
stimmt mit allen Verzeichnispfaden überein, die aus drei Einzelzeichen-Unterverzeichnissen bestehen. Da es mit einem /
endet, ist alles, was es entspricht, ein Verzeichnis, so dass es keine Notwendigkeit gibt, zu testen.
(cd "$d" && ...;)
...
ausführt, nachdem es dem entsprechenden Unterverzeichnis wechseln mit cd. Wenn Sie diesen Block in ()
setzen, wird er in einer Subshell ausgeführt, was bedeutet, dass der Gültigkeitsbereich von cd
auf den geklammerten Block beschränkt ist. Das ist einfacher und sicherer als cd ..
am Ende zu setzen.
Wir haben dann zunächst die Unterverzeichnisse zu sammeln, indem Sie die einzigartigen ursprünglichen Strings der Dateien zu finden:
printf '%.4s\0' * | uniq -z | xargs -0 ...
, dass die ersten vier Buchstaben jeden Dateinamen extrahiert, nul abbreche jeden, dann übergibt diese Liste an uniq
um die Duplikate zu eliminieren, indem die -z
Option zur Verfügung gestellt wird, da die Eingabe nullterminiert ist, und dann die Liste der eindeutigen Präfixe an xargs
weitergibt, wiederum unter Verwendung von -0
, um anzuzeigen, dass die Liste nullterminiert ist. xargs
führt einen Befehl mit einer Liste von Argumenten aus und gibt den Befehl nur dann mehrfach aus, wenn dies erforderlich ist, um eine Überschreitung des Befehlszeilenlimits zu vermeiden. (Wir hätten wahrscheinlich die Verwendung von xargs
vermeiden können, aber es kostet nicht viel und es ist viel sicherer.)
Der mit xargs aufgerufene Befehl ist bash; Wir verwenden die Option -c
, um einen auszuführenden Befehl zu übergeben. Dieser Befehl iteriert seine Argumente mithilfe der Syntax for arg in
. Jedes Argument ist ein eindeutiges Präfix. Wir extrahieren das vierte Zeichen aus dem Präfix, um das neue Unterverzeichnis zu erstellen, und dann mv
alle Dateien, deren Namen mit dem Präfix im neu erstellten Verzeichnis beginnen.
Die _
am Ende des Aufrufs xargs
wird an bash
weitergegeben (wie bei allen anderen Argumenten); bash -c
verwendet das erste Argument nach dem Befehl als $0
-Argument für das Skript, das nicht Teil der Befehlszeilenargumente ist, die von der for arg in
-Syntax durchlaufen werden. Die _
zu setzen bedeutet also, dass die Argumentenliste, die durch xargs
erstellt wird, genau $1
, $2
, ... in der Ausführung des Bash-Befehls ist.
Mit welchem Teil Ihrer ursprünglichen Frage haben Sie Probleme? Es ist im Wesentlichen das gleiche Konzept. –
Schleife durch die vorhandene Verzeichnisstruktur, ohne die neu erstellten Ordner einzugeben – Dan
Warum Schleife überhaupt? 'cd f/i/l; mkdir e; cp * e; rm * 'sollte tun, was Sie wollen ... (Sie sollten das letzte' rm' in 'echo' ändern, um es zuerst zu testen) ... –