Ich habe eine Liste von Ordnern, die Datumsangaben für Namen haben. Die Datumsangaben haben das Format JJJJMMTT (z. B. 20150129). In diesen Ordnern befinden sich Textdokumente, die sich auf dieses bestimmte Datum beziehen.
Ich möchte sie in einer Ordnerhierarchie von Jahr zu Monat bis Datum neu strukturieren und die Textdokumente in den entsprechenden Ordner "Datum" weiter unten in der Hierarchie verschieben.
Mit anderen Worten, ich möchte, dass der Stammordner nach dem Jahr wie 2015 benannt wird, und dann Unterordner mit Namen wie 01 erstellt und dann weitere Unterordner mit Datumsangaben wie 29 erstellt, die die entsprechenden Textdokumente enthalten .
Der Pfad würde also wie folgt aussehen 2015/01/29/file.txt
oder 2015>01>29>file.txt
.
Ich habe mir Automator angesehen und es scheint, dass so etwas nicht möglich ist, obwohl ich mich irren könnte, also würde ich gerne wissen ...
Gibt es eine einfache Lösung für dieses Problem, die jeder Laie verstehen kann, beispielsweise einen Automator-Workflow, oder erfordert dies ein gewisses Verständnis von Terminalbefehlen und regulären Ausdrücken?
Wie würde man dieses Problem lösen, sofern es tatsächlich eine Lösung gibt?
Angenommen, alle diese YYYYMMDD-Ordner sind Teil desselben übergeordneten Verzeichnisses, das Sie ausführen könnten
cd PARENT_DIRECTORY
for d in */; do
[[ $d =~ [0-9]{8}/ ]] || continue
mkdir -p -- "${d:0:4}/${d:4:2}"
mv -- "$d" "${d:0:4}/${d:4:2}/${d:6:2}"
done
for d in */; do
Schleife liest alle Verzeichniseinträge, das Trailing /
stellt sicher, dass nur Verzeichnisnamen tatsächlich übereinstimmen[[ $d =~ [0-9]{8}/ ]]
testet, ob die aktuelle Eingabe aus 8 Ziffern besteht, und fährt mit der nächsten Eingabe fort, wenn nicht${d:0:4}/${d:4:2}/${d:6:2}
verwendet die Parametererweiterung innerhalb bash
, um eine Zeichenfolge zu erstellen, die den neuen Pfad enthält--
in beiden verhindert Probleme mkdir
, mv
falls der Verzeichnis- oder Dateiname mit einem -
. Dies kann hier nicht passieren, aber es ist wahrscheinlich trotzdem eine gute Praxis.Danke an @terdon und @user3439894 für Ideen zur Verbesserung des ursprünglichen Skripts.
Sie können Folgendes im Terminal verwenden. cd
in den enthaltenden Ordner, und führen Sie dann Folgendes aus:
find . -type f -exec bash -c \
'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})#\1/\2/\3#" <<< $1);\
mkdir -p -- $(dirname "$F");\
mv -- "$1" "$F"' - {} \;
find . -type f
erhält jede Datei im aktuellen Verzeichnis rekursiv.
-exec bash -c
öffnet eine Shell, um die folgenden Befehle auszuführen.
F=$(…)
öffnet eine Subshell und verwendet sed für den Dateipfad, um den Pfad in die Ordner zu manipulieren.
^\./([0-9]{4})([0-9]{2})([0-9]{2})
ist eine Regex mit drei Erfassungsgruppen, wie folgt: ist Ersatz, wobei jede Erfassungsgruppe ( , usw.) durch getrennt ist . erstellt die Verzeichnisse, in die die Dateien verschoben werden. verschiebt jede Datei in den entsprechenden Ordner.
\1/\2/\3
\1
/
mkdir -p -- $(dirname "$F")
mv -- "$1" "$F"
Dies nimmt die Hierarchie auf der linken Seite und konvertiert sie in die Hierarchie auf der rechten Seite:
├── 20170201 └── 2017
│ └── abcdefghij ├── 02
└── 20170302 │ └── 01
└── abcdefghij 2 │ └── abcdefghij
└── 03
└── 02
└── abcdefghij 2
Wenn sich im enthaltenden Ordner andere Dateien mit einem Datum als Namen befinden, werden sie verschoben, als wären sie ein Ordner. Um dies zu verhindern, ersetzen Sie die zweite Zeile durch:
'F=$(sed -E "s#^\./([0-9]{4})([0-9]{2})([0-9]{2})(?:/.+)#\1/\2/\3#" <<< $1);\
Das (?:/.+)
stellt sicher, dass der Pfad eine nachfolgende Komponente hat, und ignoriert daher alles ohne untergeordnete Elemente im übergeordneten Verzeichnis, bei denen es sich um Dateien handelt.
Benutzer3439894
kein Hang
davidjnatarajan