Wie kann ich per Script Dateien in Unterordner verschieben?

Hallo,

ich bin langsam etwas ratlos und sehe vermutlich den Wald vor lauter Bäumen nicht mehr. Ich habe folgendes Problem:

Ich muss zwecks Neustrukturierung einen Haufen Dateien verschieben und würde das gerne per SH-Script machen. Da ich dieses Beispiel schon öfter jetzt bei meiner Recherche gefunden habe, behalte ich es einfach bei, da es auch egal sein sollte was für Dateien wie verschoben werden sollen.

Jetzige Struktur

  • Hauptordner
    - Ordner 1
    - Datei 1.ext
    - Datei 2.ext
    - Datei 3.ext
    - Datei 4.ext
    - Datei 5.ext
    - Ordner 2
    - Datei 1.ext
    - Datei 2.ext
    - Datei 3.ext
    - Datei 4.ext
    - Datei 5.ext

Die Dateien sind verschiedenster Dateierweiterungen. Jetzt hätte ich gerne folgende Strucktur

  • Hauptordner
    • Ordner 1
      - Ordner aus Datei 1
      Datei 1.ext
      - Ordner aus Datei 2
      Datei 2.ext
      - Ordner aus Datei 3
      Datei 3.ext
      - Ordner aus Datei 4
      Datei 4.ext
      - Ordner aus Datei 5
      Datei 5.ext
    • Ordner 2
      - Ordner aus Datei 1
      Datei 1.ext
      - Ordner aus Datei 2
      Datei 2.ext
      - Ordner aus Datei 3
      Datei 3.ext
      - Ordner aus Datei 4
      Datei 4.ext
      - Ordner aus Datei 5
      Datei 5.ext

Obwohl ich so gut wie sicher bin das bei der Dateispeicherung keine Umlaute benutzt wurden, wäre es schön wenn Dateien mit umlauten ignoriert werden.

Was habe ich bis jetzt versucht?
Ich wollte das ganze mit schleifen (loops) machen, aber das wird nicht getan, auch nicht das Umlaute und Leerzeichen entfernen und ich weiss nicht warum

Um evtl. vorhandene Umlaute umzuenennen und Leerzeichen zu entfernen.

for file in *.*; do mv -v $file `echo $file | sed -e "s/ä/ae/g"`; done
for file in *.*; do mv -v $file `echo $file | sed -e "s/ö/oe/g"`; done
for file in *.*; do mv -v $file `echo $file | sed -e "s/ü/ue/g"`; done
for file in *.*; do mv -v $file `echo $file | sed -e "s/ß/ss/g"`; done
for file in *.*; do mv -v $file `echo $file | sed -e "s/Ä/Ae/g"`; done
for file in *.*; do mv -v $file `echo $file | sed -e "s/Ö/Oe/g"`; done
for file in *.*; do mv -v $file `echo $file | sed -e "s/Ü/Ue/g"`; done
for file in *.*; do mv -v $file `echo $file | sed -e "s/ /_/g"`; done

Zum kopieren dann das

for file in *.*; do mv $i ${i%.*}/*.*; done

Betriebssystem ist Debian genauer Openmediavault.

Ich hoffe mir kann hier jemand sagen wo mein Fehler ist, oder hat ein Script zur Hand welches er mir zur Verfügung stellen kann.

Lieben Gruss
Michael

Hallo,

ich verstehe deine neue Struktur nicht, wenn ich ehrlich bin.
Leider schreibst du auch nicht, was an deinem Kopier-Befehl nicht funktioniert.

Und warum verwendest du *.*? Ist das ein altes DOS-Überbleibsel?
Wenn du nur Dateien meinst solltest du entweder mit „test -f“ schauen, ob es sich um eine Datei handelt oder mit „find . -type f“ nur Dateien finden und iterieren.

Gruß,
Steve

Hallo Steve, danke für die Antwort.

Ich hätte gerne das aus dem Dateinamen ein neuer Ordner gemacht wird und diese Datei dann in diesen neuen Ordner verschoben wird.

Beispiel:
jetzt ich_bin_ein_foto.jpg und soll ich_bin_ein_foto/ich_bin_ein_foto.jpg
oder
ich_bin_ein_film.avi und soll ich_bin_ein_film/ich_bin_ein_film.avi

. Da in dem Ordner Dateien Verschiedenster Erweiterungen drin sind, also Fotos, Filme und Dokumente und ich das bis jetzt immer mit diesem Befehl gemacht habe, kann sein das ich das seid DOS so mache, hat bis jetzt allerdings auch immer funktioniert :sweat_smile:

Damit wird es klarer. Dann fehlt natürlich ein „mkdir“ denn du musst die entsprechenden Ordner natürlich zunächst erstellen, bevor du Dateien hinein verschieben kannst.

Gruß,
Steve

Danke, wie gesagt der Wald vor lauter Bäumen :wink:

Aber jetzt habe ich das nächste Problem, hab mir ein kleines Script zur „Trockenübung“ erstellt, bekomme allerdings ein für mich nicht nachvollziehbarer Syntaxfehler.

Script copy.sh

#!/bin/sh
extensions='.mkv .avi .mp4 .jpg .mpg .bmp .pdf .txt .doc .xls'
for ext in $extensions; do
clear
echo ''
echo ''
echo 'Dateinamen werden bearbeitet...'
echo ''
echo ''
for file in $ext; do
	echo 'Umlaut "Ä" wird in "AE" getauscht...'
	mv -v $file `echo $file | sed -e "s/ä/ae/g"`
	mv -v $file `echo $file | sed -e "s/Ä/Ae/g"`
	echo ''
	echo ''
	echo 'Umlaut "Ö" wird in "OE" getauscht...'
	mv -v $file `echo $file | sed -e "s/ö/oe/g"`
	mv -v $file `echo $file | sed -e "s/Ö/Oe/g"`
	echo ''
	echo ''
	echo 'Umlaut "Ü" wird in "UE" getauscht...'
	mv -v $file `echo $file | sed -e "s/ü/ue/g"`
	mv -v $file `echo $file | sed -e "s/Ü/Ue/g"`
	echo ''
	echo ''
	echo 'Umlaut "ß" wird in "ss" getauscht...'
	mv -v $file `echo $file | sed -e "s/ß/ss/g"`
	echo ''
	echo ''
	echo 'Ordner werden anhand der Dateinamen erstellt und die Dateien kopiert...'
	ordner="${file%.*}"
	mkdir -- "$ordner"
	mv -- "$file" "$ordner"	
 done
done

die erhalte Fehlermeldung:
copy.sh: 3: copy.sh: Syntax error: word unexpected (expecting „do“)

allerdings muss da eine do-anweisung hin, also langsam zweifel ich echt an mir. Vielleicht ist es auch schon zu spät. Ich geh dann erstmal schlafen. Gute Nacht

Gruß Michael

Mit welcher Shell führst du das Skript aus? /bin/sh ist ja meist ein symbolischer Link auf dash, bash oder eine andere Shell. Ich bekomme diesen Fehler mit bash jedenfalls nicht.

Das hier wird aber auf keinen Fall funktionieren:

for file in $ext; do

Da fehlt ein Wildcard-Stern. Aber auch wenn der Stern da ist, wird es nicht funktionieren, wenn es keine Datei des entsprechenden Typs gibt. In diesem Fall liefert z.B. *.xls als Ergebnis die Zeichenkette „*.xls“. Um das zu vermeiden, kann man folgende Anweisung einfügen:

shopt -s nullglob

Hallo Axurit,

danke für die Antwort, ich greife auf den Server per putty zu. Ich muss leider feststellen, das ich es einfach nicht hin bekomme, warum auch immer. Ich bekomme immer den selben Fehler, der mittlerweile so aussieht

root@ThXXXXX# bash copy.sh
copy.sh: Zeile 4: Syntaxfehler beim unerwarteten Wort `$'do\r''
'opy.sh: Zeile 4: `do
root@ThXXXXX#

Und es ist egal ob ich es per bash copy.sh per ./copy.sh oder per /bin/bash ./copy.sh aufrufe. Immer wieder der obige Fehler.

Das \r deutet darauf hin, dass es wohl ein Problem mit dem Dateiformat gibt, Unix-Dateien enthalten kein \r am Zeilenende.

Noch ein paar Tipps zum Debuggen von Shell-Skripts: In der Testphase würde ich das „clear“ auskommentieren, weil es unter Umständen Fehlermeldungen löscht. Und wenn es Probleme mit einer Anweisung gibt, dann sollte man alle darin verwendeten Variablen zuvor mit „echo“ auf der Konsole anzeigen. Wenn man wissen will, wie ein Befehl, der Variablen enthält, expandiert tatsächlich aussieht, kann man ihn zunächst in eine Variable schreiben, diese anzeigen und dann mit eval ausführen. Beispiel:

CMD="mv $file $dir"
echo $CMD
eval $CMD
1 Like

Moin,
brauchst du noch eine Lösung für dein Problem der Umlautentfernung? Ich habe seit Jahren ein Script, was das und noch ein paar andere Sachen macht (z.B. prüft, ob es den Zieldateiname schon gibt. Sonst wird gerne oe.txt durch die umbenannte ö.txt überschrieben).
Das könnte ich noch mal raus suchen.

VG
J~

Hallo J,

Ja ich habe das Problem immer noch, wenn du das Script noch hast und es nicht zu viel Arbeit ist würde ich mich freuen wenn du es mir zur Verfügung stellen würdest.

Lg

Moin,

Ja ich habe das Problem immer noch, wenn du das Script noch hast und es nicht zu
viel Arbeit ist würde ich mich freuen wenn du es mir zur Verfügung stellen würdest.

nö, ist nicht viel Arbeit, aber ich wollte es auch nicht unnötig hier rein stellen :smile:

HTH,
J~

Hier sollte eigentlich das Script stehen.
Aber sorry, in diesem blöden neuen Editor kann man leider kein Script mehr vernünftig formatieren, auch mit < code > nicht. Werde versuchen es dir zu mailen.

edit: der interne Mailer hier kann auch nicht damit umgehen und verhunzt die Formatierungen. Bitte nenn’ mir doch mal eine eMail-Adresse wo ich das hin schicken kann