
Ich versuche, Dateien wie folgt zu verschieben:
...
DLG023-00-01-sprite.TextGrid.json
DLG023-00-01.prosody.json
DLG023-01-01-sprite.ogg
DLG023-00-02-sprite.TextGrid.json
DLG023-00-02.prosody.json
DLG023-01-02-sprite.ogg
...
DLG028-00-01-sprite.TextGrid.json
DLG028-00-01.prosody.json
DLG028-01-01-sprite.ogg
...
in die jeweiligen Ordner, z. B.: Verschieben Sie die Datei dorthin, dialogue023/
wenn sie mit beginnt DLG023
; dorthin, dialogue024/
wenn sie mit beginnt DLG024
; und so weiter.
Alle Dateien und Verzeichnisse befinden sich auf derselben Ebene.
Mit anderen Worten versuche ich, Befehle wie diesen zu erzeugen:
mv DLG023-00-01-sprite.ogg dialogue023/
Wie kann ich die erste Zahl aus dem Dateinamen extrahieren?
Bisher habe ich Folgendes:
for i in DLG*-*-*-sprite.ogg; do echo "${i//[^0-9]}";done
Dies gibt jedoch alle Ziffern aus (z. B. 230001), obwohl ich nur die erste Ziffer möchte (z. B. 23).
Antwort1
Ich gehe davon aus, dass Sie OS X verwenden, wo diese -t
Option nicht verfügbar ist mv
. Dies wird quälend langsam sein, wenn das Skript Tausende von Dateien verarbeitet.
for file in DLG*; do
# Extract the three digits after DLG
getnum=${file%%-*}
getnum=${getnum#???}
# make the directory dialogue### or exit if there is an error
echo mkdir -p "dialogue${getnum}" || exit
echo mv "$file" "dialogue${getnum}"
done
Entfernen Sie das „ echo
Vorher“ mkdir
und mv
„Wenn die Ausgabe zufriedenstellend ist“.
Antwort2
Sie können den mv-Befehl folgendermaßen generieren:
for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done
Jetzt werden die Befehle folgendermaßen ausgedruckt:
mv "DLG023-00-01.prosody.json" "dialogue023/"
[...]
mv "DLG028-00-01.prosody.json" "dialogue028/"
[...]
Wenn es das ist, was Sie möchten, leiten Sie die Ausgabe einfach weiter an bash
:
for f in DLG*; do echo "$f" | sed 's/DLG\([0-9]\+\).*/mv "\0" "dialogue\1\/"/g'; done | bash
Antwort3
Einzeilige Lösung mit find
:
find . -name DLG* -exec bash -c 'DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/"); mkdir "$DEST"; mv "$0" "$DEST"' {} \;
find
Der Befehl sucht nachDLG*
Dateien aus diesem Verzeichnis.- Führen Sie für jedes Ergebnis den
bash -c
Satz aus.
In dem bash
Satz:
DEST=$(echo "$0" | sed -r "s/DLG([0-9]+)-.*/dialogue\1/");
wählt jedes Ergebnis aus find ($0
) aus,sed
ersetzt alle Zahlen vor der ersten-
(DLG([0-9]+)-.*) durchdialogue
die folgenden Zahlen (dialogue\1
) und setzt sie in eine Variable namens einDEST
.mkdir "$DEST"
erstellt den erforderlichen Ordner.mv "$0" "$DEST"'
verschiebt die Datei in dieses Verzeichnis.
Antwort4
Ein paar Ideen:
for i in DLG*-\*-\*-sprite.ogg; do echo "${i//[^0-9]}" | head -c 2; echo ;done
Wenn Sie sicher sind, dass sie alle gleich lang sind:
for i in DLG*-\*-\*-sprite.ogg; do echo "${i:3:3}" ;done