dateinamen öäüß erstzen durch oe ae ue ss

Message
Author
User avatar
frank rudolph
Posts: 146
Joined: 13. Apr 2004 12:18
Location: Giessen
Contact:

dateinamen öäüß erstzen durch oe ae ue ss

#1 Post by frank rudolph »

Hallo
Ich möchte in einem Pfad mit Unterverzeichnissen alle Umlaute und ß ersetzen durch oe ae ue und ss .
Meine Lösung ist ein kleines Basic Programm (Gambas) welches ein LS in eine Datei macht und die dann Zeilenweise abgearbeitet wird.
sehr sehr langsam ...... :-((

Da gibt es doch bestimmt einen schnellen pearl oder bash script das dieses Problem mit reg ex löst???
Oder gibt es einen ganz anderen Ansatz
Kann mir jemand hefen?

mfg
Frank

k2
Posts: 1
Joined: 27. Jan 2002 13:29

Damit sollte es gehen:

#2 Post by k2 »

Code: Select all

#!/bin/sh
#
# Umlaute und ß in Dateinamen im aktuellen Verzeichnis ersetzen

for i in *; do
        ii=`echo $i | sed -e's/ä/ae/g' -e's/ö/oe/g' -e's/ü/ue/g' -e's/Ä/Ae/g' -e's/Ö/Oe/g' -e's/Ü/Ue/g' -e's/ß/ss/g'`
if [ $i != $ii ] ; then
        mv $i $ii 
        echo "Datei $i wurde in $ii geändert!"
fi
done
Die sed-Befehle müssen in einer Zeile stehen!

mfG k2

User avatar
frank rudolph
Posts: 146
Joined: 13. Apr 2004 12:18
Location: Giessen
Contact:

unterverzeichnisse

#3 Post by frank rudolph »

Hallo
Erst mal vielen vielen Dank K2.
Das hilft mir schon mal ne ecke weiter. Habe auch das meiste verstanden :-)

Ich kann bash scripting noch nicht so gut aber ich denke das bei diesem script
die Unterverzeichnisse nicht berücksichtigt werden. (wäre aber wichtig)
Wenn ich auch die Leerzeichen eliminieren möchte würde das mit -e's/ //g' gehen ?

Ich kann nun mit ls eine Datei erstellen mit allen Verzeichnisnamen und dann dein script in eine weitere for schleife packen - die aus der erstellten Datei die Pfad und verzeichnisnamen nimmt und dann die For Schleife für jeden dateinamen durchläuft.
Das wäre die Lösung mit meinen bescheidenen mitteln (kenntnissen)

Wenn noch jemand eine elegantere Lösung kennt - würde mich freuen!!!!
mfg Frank

User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

#4 Post by Lateralus »

Hier eine kleine abgewandelte Form des obigen Scripts, welches sich rekursiv durch die Verzeichnisse arbeitet:

Code: Select all

#!/bin/sh
#
# Umlaute und ß in Dateinamen im aktuellen Verzeichnis ersetzen

# Trennung zwischen Dateinamen ist Newline:
IFS="
"

for i in $(find . -type f); do
        ii=`echo $i | sed -e's/ä/ae/g' -e's/ö/oe/g' -e's/ü/ue/g' -e's/Ä/Ae/g' \
        -e's/Ö/Oe/g' -e's/Ü/Ue/g' -e's/ß/ss/g' -e's/ //g'`
if [ $i != $ii ] ; then
        mv $i $ii
        echo "Datei $i wurde in $ii geändert!"
fi
done
Das müsste funktionieren, wenngleich es Probleme geben könnte, falls die Unterverzeichnisse selbst Umlaute besitzen, da in $i jetzt der gesamte Pfad ab dem aktuellen plus Dateinamen steht.

User avatar
frank rudolph
Posts: 146
Joined: 13. Apr 2004 12:18
Location: Giessen
Contact:

eine frage noch

#5 Post by frank rudolph »

Vielen Dank Lateralus ......

Zwei Fragen hätte ich noch!
Ich dachte durch das find -type f würde sich das Script sowieso nur auf Dateien und nicht auf Verzeichnisse beziehen.

Wenn ich aus dem f ein d mache würde es dann nur Verzeichnisnamen korrigieren?
Wenn ja dann könnte ich zwei Durchläufe machen ... erst die Verz. dann die Dateien.

Leerzeeichen werden bei diesem Script auch ausgefiltert!!!!

In der ersten Zeile steht IFS=" und das nächste " steht in einer neuen Zeile, soll das so sein?
Die Rekursion ergibt sich automatisch durch den Einsatz von find!!!!

Habe ich alles richtig verstanden ?
Wenn du Lust und Zeit hast kannst du ja nochmal kurz antworten.
mfg
Frank

User avatar
Lateralus
prolinux-forum-admin
Posts: 1238
Joined: 05. May 2004 7:35

#6 Post by Lateralus »

Das Problem ist, dass dir dennoch der gesamte Pfad angezeigt wird:

Code: Select all

find / -type f | grep XF86Conf
/etc/X11/XF86Config
und dann werden die Verzeichnisse natürlich mit korrigiert. Das

Code: Select all

IFS="
"
ist korrekt. Dazwischen darf auch nur der Zeilenumbruch stehen, denn genau das ist das Zeichen, was die Dateinamen trennen soll. Andernfalls würde bei der For-Schleife ein Element auch mit Leerzeichen und TAB getrennt.

Das Problem an dem zwei-mal durchlaufen lassen ist dann widerum, dass die Verzeichnisnamen ermittelt werden, bevor die Umbennenung stattfindet. Wenn du also die Verzeichnisse

./Überbleibsel/Ähnliches

hast, erzeugt dein find . -type d folgendes:

Code: Select all

./Überbleibsel
./Überbleibsel/Ähnliches
Dieser werden dann in dieser Reihenfolge umbenannt. Natürlich kann die zweite Umbennenung nicht stattfinden, weil "Überbleibsel" nicht mehr existiert.

Ich bin hier allerdings am Ende meiner Skriptfähigkeit angekommen...

EDIT: vielleicht funktiniert das ganze mit der -exec Funktion von find:

Code: Select all

#!/bin/sh
IFS="
"

find . -exec "newname=$(echo {} | sed -e's/ä/ae/g' -e's/ö/oe/g' -e's/ü/ue/g' -e's/Ä/Ae/g' \
-e's/Ö/Oe/g' -e's/Ü/Ue/g' -e's/ß/ss/g' -e's/ //g'); mv {} $newname" \;

User avatar
frank rudolph
Posts: 146
Joined: 13. Apr 2004 12:18
Location: Giessen
Contact:

danke

#7 Post by frank rudolph »

Vielen Dank !!!!
Mehr Infos brauche ich auch nicht. Das reicht mir völlig.
Ich habe auch alles verstanden - das bekomme ich dann schon hin.
(denke ich :-) )
mfg
frank

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#8 Post by jochen »

Schade, dass ich diesen Thread nicht etwas früher gesehen habe...

Trotzdem gebe ich jetzt noch mal meinen Senf dazu. :)

Code: Select all

#!/bin/bash

find . -iname "*[äöüß]*" -depth -print | \
awk '
{
        match ($0,/.*\//)
        name = substr ($0,RLENGTH+1)
        pfad = substr ($0,1,RLENGTH)
        gsub (/ä/,"ae",name)
        gsub (/ö/,"oe",name)
        gsub (/ü/,"ue",name)
        gsub (/ß/,"ss",name)
        gsub (/Ä/,"Ae",name)
        gsub (/Ö/,"Oe",name)
        gsub (/Ü/,"Ue",name)
        print "mv '\''" $0 "'\'' '\''" pfad name "'\''"
}' | cat
find liefert uns wg. -iname "..." nur Datei-/Verzeichnisnamen, die auch Umlaute enthalten. -depth sorgt dafür, dass erst der Inhalt eines Verzeichnisses aufgelistet wird, bevor das Verzeichnis selbst alleine auftaucht.

Im awk finden wir mittels match() das letzte "/" im Namen und kopieren uns einmal den Pfad der Datei und den Dateinamen selbst heraus. Der Dateiname wird dann von Umlauten befreit (gsub()) und zum Schluss ein mv-Kommando aus dem Originalnamen und dem neuen Namen gebastelt.

Zu Testzwecken schicke ich solche "Shellscripts-on-the-fly" immer durch cat. So erhalte ich die Kommandos, die das Skript erzeugt, ausgegeben. Beispiel:

Code: Select all

jochen@joe$ ./mvumlaut.sh
mv './ärger/häßlich' './ärger/haesslich'
mv './ärger' './aerger'
mv './schlümpf/töricht' './schlümpf/toericht'
mv './schlümpf' './schluempf'
jochen@joe$
WIe man sieht, sorgt -depth dafür, dass ./ärger/häßlich vor ./ärger behandelt wird und dass so der Pfadname seine Gültigkeit nicht verliert.

Wenn einem der Output so gefällt, ersetze man den letzten Bestandteil der Pipeline, also das cat, durch "sh -ev". Die Shell führt die mv-Kommandos dann aus, bricht ab, wenn ein mv-Kommando fehlschlagen sollte (-e) und zeigt, welche Zeilen sie ausführt (-v).

Jochen
Die grösste Lüge der EDV? "Mal eben..."

User avatar
frank rudolph
Posts: 146
Joined: 13. Apr 2004 12:18
Location: Giessen
Contact:

wow wasn Brett ....

#9 Post by frank rudolph »

Hi
Das ist ja ein klasse Script.
Habe es nur mal kurz überflogen aber gleich gesehen das ich ja grosse und kleine Umlaute bisher gar nicht berücksuchtigt habe!!!!!
Kann ich das so für Leerzeichen einfach erweitern?
gsub (/ /,"",name)
Ich werde das ganze Script genauestens untersuchen und melde mich auf jeden Fall nochmal.

Vielen Vielen Dank
mfgFrank

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

#10 Post by jochen »

Code: Select all

gsub (/ /,"",name) 
Ja, genau so. Diese Zeile einfach bei den anderen gsubs einfügen. Die entsprechen übrigens ziemlich exakt dem "s///g" des seds.

Jochen
Die grösste Lüge der EDV? "Mal eben..."

User avatar
frank rudolph
Posts: 146
Joined: 13. Apr 2004 12:18
Location: Giessen
Contact:

zwei kleinigkeiten noch

#11 Post by frank rudolph »

Ja super !!!!
Wenn ich die Zeile für die Leereichen einfüge dann werden alle Leezeichen aus Datei und Verzeichnisnamen entfernt die auch einen Umlaut enthalten.

Wenn ich aus allen Datei und Verzeichnisnamen die Leerzeichen entfernen will müsste ich das bestimmt beim find . -iname "*[äöüß]*" -depth .... berücksichtigen oder?
Müsste ich das Leerzeichen dann speziell maskieren? z.B."*[äöüß' ']*" oder so?

Wenn du Tips gibst dann stehen der Code immer in einer hübschen code Box.
Wie füge ich eine solche box in den hilfetext ein?

mfg Frank

User avatar
jochen
prolinux-forum-admin
Posts: 699
Joined: 14. Jan 2000 15:37
Location: Jülich
Contact:

Re: zwei kleinigkeiten noch

#12 Post by jochen »

frank rudolph wrote:Wenn ich die Zeile für die Leereichen einfüge dann werden alle Leezeichen aus Datei und Verzeichnisnamen entfernt die auch einen Umlaut enthalten.

Wenn ich aus allen Datei und Verzeichnisnamen die Leerzeichen entfernen will müsste ich das bestimmt beim find . -iname "*[äöüß]*" -depth .... berücksichtigen oder?
*handvordiestirnpatsch* Ja klar! Habe ich total übersehen.
frank rudolph wrote:Müsste ich das Leerzeichen dann speziell maskieren? z.B."*[äöüß' ']*" oder so?
Nein, musst Du nicht. Schmeiß aus Deiner Version die Hochkommata raus, dann ist es korrekt. Denn das Muster ist bereits in Anführungszeichen eingefasst - das untersagt der Shell nicht nur die Dateinamensgenerierung (das soll ja das find-Kommando machen), sondern auch die Auftrennung von Argumenten anhand von Whitespace.
frank rudolph wrote:Wenn du Tips gibst dann stehen der Code immer in einer hübschen code Box.
Wie füge ich eine solche box in den hilfetext ein?
Wenn postest, hast Du über dem Texteingabefald eine Reihe von Buttons für fette, kursive, unterstrichene Schrift, für Zitate, Code, Listen, eingebettete Bilder und URLs. Die fügen aber letztlich nur BBCode in Deinen Text ein - die Hilfe dazu findest Du hier: faq.php?mode=bbcode.

Jochen
Die grösste Lüge der EDV? "Mal eben..."

User avatar
rdldom
Posts: 7
Joined: 13. Dec 2005 7:44
Location: Braunschweig

#13 Post by rdldom »

Code: Select all

#!/bin/bash

find . -iname "*[äöüß]*" -depth -print | \
awk '
{
        match ($0,/.*\//)
        name = substr ($0,RLENGTH+1)
        pfad = substr ($0,1,RLENGTH)
        gsub (/ä/,"ae",name)
        gsub (/ö/,"oe",name)
        gsub (/ü/,"ue",name)
        gsub (/ß/,"ss",name)
        gsub (/Ä/,"Ae",name)
        gsub (/Ö/,"Oe",name)
        gsub (/Ü/,"Ue",name)
        print "mv '\''" $0 "'\'' '\''" pfad name "'\''"
}' | cat
Sowas in der Richtung suche ich gerade händeringend. Nur muß ich aus %20 Leerzeichen machen. Aus diesem Grund habe ich das Script abgeändert:

Code: Select all

#!/bin/bash

find . -iname "*[%20]*" -depth -print | \
awk '
{
        match ($0,/.*\//)
        name = substr ($0,RLENGTH+1)
        pfad = substr ($0,1,RLENGTH)
        gsub (/$20/," ",name)
        print "mv '\''" $0 "'\'' '\''" pfad name "'\''"
}' | cat
Leider reicht das wohl nicht. Hier mal eine Ausgabe mit der Option | cat:
mv './savxp/commonappdata/sophos/sophos%20anti-virus' './savxp/commonappdata/sophos/sophos anti-virus'
Das sieht noch sehr gut aus.

Habe ich aber nun mehrere Verzeichnisse mit %20, dann sieht es leider so aus:
mv './savxp/program%20files/sophos/sophos%20anti-virus/module%20retargetable%20folder' './savxp/program%20files/sophos/sophos%20anti-virus/module retargetable folder'

Wie man sehen kann, wird nur der letzte Ordner geändert. Ordner davor werden nicht angerührt.
Nachtrag:
Ich muß die Datei mehrmals starten, dann werden nach und nach die Dateien geändert.
Sicherlich gibt es hier auch eine Lösung, oder? :lol:

Nächste Problem:
Es werden scheinbar auch Daten "versucht" zu ändern, die nichts mit "%20" zu tun haben:
mv './savxp/vdl01.vdb' './savxp/vdl01.vdb'
mv './savxp/vdl02.vdb' './savxp/vdl02.vdb'


Schalte ich das Programm mit "sh -ev" (einfach um schon mal etwas zu ändern), bekomme ich die Meldung:
mv './libeay32.dll' './libeay32.dll'
mv: `./libeay32.dll' and `./libeay32.dll' are the same file

Und das war es auch schon.

Tipps?

Dickes Dankeschön schonmal vorab
Frank

klopskuchen
prolinux-forum-admin
Posts: 1444
Joined: 26. Jun 2004 21:18
Contact:

#14 Post by klopskuchen »

Code: Select all

#/bin/sh
 
ls $1*%20* >/tmp/change.txt
 
while read LINE; do
 
    NEWLINE=`echo $LINE |sed s/%20/' '/`
    echo $NEWLINE 
    #mv $LINE "$NEWLINE"
     
done < /tmp/change.txt
 
rm -rf /tmp/change.txt
 
exit 0;

Aufruf: script_name /absoluter_Pfad_zum Verzeichnis/ (mit abschließendem Schrägstrich).
Wenn die Ausgabe i.O. ist, entferne die Raute vor der Zeile mir dem mv.


MfG, Klopskuchen
When all else fails, read the instructions .

User avatar
rdldom
Posts: 7
Joined: 13. Dec 2005 7:44
Location: Braunschweig

#15 Post by rdldom »

Hallo,
danke dir, wird doch gleich mal am Montag gestet.

Nachtrag:
Getestet. Wenn ich es das Programm ausführe, bekomme ich:

Code: Select all

ls&#58; /group/sophos/Homepage/ESXP/*%20*&#58; No such file or directory
Frank

Post Reply