humanoid1
Anmeldungsdatum: 15. März 2022
Beiträge: 41
Wohnort: Jena
|
Hallo, mir fällt keine Lösung ein für folgendes Problem. Mehrere Dateinamen sollen geändert werden, und zwar nach dem Muster einschließlich "[" bis einschliesslich "]".
Ich wollte es gern mit "sed" realisieren. Es muss aber nicht zwingend mit "sed" realisiert werden, aber ohne rename-Pakete, da diese sehr unterschiedlich arbeiten. Beispiel:
| titel-beschreibung [08154711].mp4
name-beschreibung [wq154713].mp4
...
ändern in
titel-beschreibung.mp4
name-beschreibung.mp4
|
Danke für euer Wissen und eure Zeit!
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13219
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | $ cat data
titel-beschreibung [08154711].mp4
name-beschreibung [wq154713].mp4
...
ändern in
titel-beschreibung.mp4
name-beschreibung.mp4
$ sed -re 's#^(.*) \[[^][]*\](\.mp4)$#\1\2#' data
titel-beschreibung.mp4
name-beschreibung.mp4
...
ändern in
titel-beschreibung.mp4
name-beschreibung.mp4
|
Den Rest bekommst Du selbst hin. ☺
|
humanoid1
(Themenstarter)
Anmeldungsdatum: 15. März 2022
Beiträge: 41
Wohnort: Jena
|
Danke für die Antwort.
Wie kann ich data mit den richtigen Variablen ersetzen? | $ sed -re 's#^(.*) \[[^][]*\](\.mp4)$#\1\2#' /home/user/mp4-files/*
|
?
|
wxpte
Anmeldungsdatum: 20. Januar 2007
Beiträge: 1388
|
humanoid1 schrieb: Wie kann ich data mit den richtigen Variablen ersetzen?
for-Schleife?
|
shiro
Supporter
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1280
|
Meinst du so was?
$ touch "titel-beschreibung [08154711].mp4" "name-beschreibung [wq154713].mp4"
$ ls
'name-beschreibung [wq154713].mp4' 'titel-beschreibung [08154711].mp4'
$ # Anzeigen der Ergebnisse
$ find -type f -name "*.mp4" | sed -E 's/^(.*) \[.*\](.*)$/mv "&" "\1\2"/'
mv "./titel-beschreibung [08154711].mp4" "./titel-beschreibung.mp4"
mv "./name-beschreibung [wq154713].mp4" "./name-beschreibung.mp4"
$ # Umbenennung mit "e" am Ende
$ find -type f -name "*.mp4" | sed -E 's/^(.*) \[.*\](.*)$/mv "&" "\1\2"/e'
$ ls
name-beschreibung.mp4 titel-beschreibung.mp4
$ PS: Oops... rklm war schneller
|
humanoid1
(Themenstarter)
Anmeldungsdatum: 15. März 2022
Beiträge: 41
Wohnort: Jena
|
wxpte schrieb: for-Schleife?
| for file in *\[*\].mp4; do mv "$file" "${file/ \[*\]/}"; done
|
funktioniert leider nicht.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13219
|
Nicht so kompliziert denken | for f in *.mp4; do
ff=$(basename "$f" | sed ...)
mv "$f" "$(dirname "$f")/$ff"
done
|
Das ganze kann man mit find kombinieren, falls es über mehrere Verzeichnisebenen ausgeführt werden soll: | find -type f -name \*.mp4 -exec sh -c '
for f; do
ff=$(basename "$f" | sed ...)
mv "$f" "$(dirname "$f")/$ff"
done
' -- {} +
|
Bearbeitet von rklm: Schleife korrigiert
|
shiro
Supporter
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1280
|
humanoid1 schrieb: | for file in *\[*\].mp4; do mv "$file" "${file/ \[*\]/}"; done
|
funktioniert leider nicht.
Was funktioniert da bei dir nicht? Ich habe es verwendet und hat funktioniert (nur eben nicht mit "sed"). Eventuell mal statt "mv" ein "echo" eintragen und schauen, was als Ergebnis geliefert wird. Hast du was am "globbing" geändert?
|
humanoid1
(Themenstarter)
Anmeldungsdatum: 15. März 2022
Beiträge: 41
Wohnort: Jena
|
|
humanoid1
(Themenstarter)
Anmeldungsdatum: 15. März 2022
Beiträge: 41
Wohnort: Jena
|
shiro schrieb: humanoid1 schrieb: | for file in *\[*\].mp4; do mv "$file" "${file/ \[*\]/}"; done
|
Du hast recht es funktioniert bei meinen Beispiel ☺
ABER ich hätte die echten Dateinamen als Beispiel geben sollen:
| Folge_1_Silvester_[Y3JpZDovL3dkci5kZS9CZWl0cmFnLXNvcGhvcmEtZDFkNTlkMTMtNWUwZC00NmE1LWI0MjMtN2MzNjVmM2IyMGQ0].mp4
|
Hätte nicht gedacht, dass mein Beispiel so unterschiedlich vom realen Dateinamen ist.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17625
Wohnort: Berlin
|
Der einzig relevante Unterschied ist, dass offenbar Blanks im Dateinamen nicht zwingend sind:
| for f in *mp4 ; do echo mv "$f" "${f/\[*\]/}"; done
mv Folge_1_Silvester_[Y3JpZDovL3dkci5kZS9CZWl0cmFnLXNvcGhvcmEtZDFkNTlkMTMtNWUwZC00NmE1LWI0MjMtN2MzNjVmM2IyMGQ0].mp4 Folge_1_Silvester_.mp4
mv name-beschreibung [wq154713].mp4 name-beschreibung .mp4
mv titel-beschreibung [08154711].mp4 titel-beschreibung .mp4
|
Mein Script simuliert nur den move; ohne echo wird es auch durchgeführt. Allerdings probiert es auch moves aus, wenn keine eckigen Klammern vorkommen und es kann natürlich zu Dateinamenskollisionen kommen - ist die Frage, ob man das nach menschl. Ermessen ausschließen kann, sonst könnte man vorab auf Existenz des neuen Namens testen und wie bei anderen gesehen, die eckigen Klammern in den Filterausdruck für die for-loop aufnehmen. Kollision:
|
shiro
Supporter
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1280
|
Ja, ein Blank (" ") unterscheidet sich vom Unterstrich ("_"). Somit wäre deine "for" Schleife ohne "sed" abzuändern in
$ touch "Folge_1_Silvester_[Y3JpZDovL3dkci5k-usw-N2MzNjVmM2IyMGQ0].mp4"
$ re='(.*)[ _]+\[.*\](.*)'
$ for file in *\[*\].mp4; do [[ $file =~ $re ]] && mv "$file" "${BASH_REMATCH[1]}${BASH_REMATCH[2]}"; done
$ ls
Folge_1_Silvester.mp4
$
|
humanoid1
(Themenstarter)
Anmeldungsdatum: 15. März 2022
Beiträge: 41
Wohnort: Jena
|
@shiro DANKE
JA, das ist die Lösung. Wie könnte ich 2 andere Variablen setzen, so wie x und y?
|
shiro
Supporter
Anmeldungsdatum: 20. Juli 2020
Beiträge: 1280
|
humanoid1 schrieb: Wie könnte ich 2 andere Variablen setzen, so wie x und y?
Sorry, deine Frage verstehe ich nicht. Die "bash" regex Funktion "=~" erfordert das "[[ ... ]]" Konstrukt. Mach doch mal ein Beispiel, was du mit x und y meinst.
|
humanoid1
(Themenstarter)
Anmeldungsdatum: 15. März 2022
Beiträge: 41
Wohnort: Jena
|
Danke für Deine Mühe.
Beispieldatei:
| Folge_1_Silvester_[Y3JpZDovL3dkci5kZS9CZWl0cmFnLXNvcGhvcmEtZDFkNTlkMTMtNWUwZC00NmE1LWI0MjMtN2MzNjVmM2IyMGQ0].mp4
Also statt den eckigen Klammern nun * und #
Folge_1_Silvester_*Y3JpZDovL3dkci5kZS9CZWl0cmFnLXNvcGhvcmEtZDFkNTlkMTMtNWUwZC00NmE1LWI0MjMtN2MzNjVmM2IyMGQ0#.mp4
|
Wie in Deinem genialen Einzeiler müsste ich wohl das so ändern?
| for file in *\**\#.mp4; do [[ $file =~ $re ]] && mv "$file" "${BASH_REMATCH[1]}${BASH_REMATCH[2]}"; done
|
|