Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
-
swar0g
- Beiträge: 289
- Registriert: 12.12.2002 22:07:17
- Wohnort: Hannover
Beitrag
von swar0g » 17.02.2006 15:32:37
Ich brauche so ein Skript, der wie folgt aussieht
Code: Alles auswählen
for file=$( find -maxdepth 3 -name blabla ) ; do
newfile = $file $( echo $file | sed s/.alteendung/.neueendung/g )
befehl $file $newfile
done
Wobei das Problem ist, das in den Dateinamen es regelrecht von Sonderzeichen wimmelt, auch in den Verzeichnisnamen, die ja recursiv abgearbeitet werden.
Also kommen sehr häufig Klammern, Leerzeichen und " ' in den Dateinamen vor.
Wie geht man am besten vor?
d3 d0 c1 d3 c9 20 cd c9 d2 2c 20 d5 c2 c5 ca 20 d3 c5 c2 d1 0a
-
roli
- Beiträge: 3174
- Registriert: 10.09.2003 17:39:58
Beitrag
von roli » 17.02.2006 19:12:32
Hi,
Code: Alles auswählen
for file in $( find -maxdepth 3 -name blabla )
do
newfile=$( echo $file | sed s/.alteendung/.neueendung/g )
befehl $file $newfile
done
wenn du in der "for" Zeile aus dem "=" ein "in" machst, sollte es schon fast gehen. Jetzt noch die newfile Zeile aendern (siehe oben) und ich denke, das ist es was du suchst, oder?
Roland
"Aber wenn du schon so unwissend bist, davon noch nicht gehört zu haben,
so will ich es doch als gut ansehen, daß du lieber einmal töricht fragst,
als weiterhin nichts von etwas zu wissen, das man doch wissen sollte."
aus "Die Edda des Snorri Sturluson", "Gylfis Täuschung"
-
Methusalix
Beitrag
von Methusalix » 17.02.2006 19:45:53
Hallo,
von dem = Zeichen mal abgesehen: mit Deinem Befehl änderst Du per sed ja nur die Dateiendung (wenn nicht mehrere Punkte im Dateinamen vorkommen). Wo sind den die Sonderzeichen? Sonderzeichen müssen gegebenenfalls mit sed gequotet werden.
Auch Leerzeichen kannst Du mit sed filtern.
bedeutet: befehl
mv $file $newfile
? (was ja Sinn machen würde)?
Vielleicht solltest Du mal einen repräsentativen (soweit vorhanden) Dateinamen posten.
Gruß
Matthias
-
swar0g
- Beiträge: 289
- Registriert: 12.12.2002 22:07:17
- Wohnort: Hannover
Beitrag
von swar0g » 17.02.2006 19:52:05
roli hat geschrieben:Hi,
Code: Alles auswählen
for file in $( find -maxdepth 3 -name blabla )
do
newfile=$( echo $file | sed s/.alteendung/.neueendung/g )
befehl $file $newfile
done
wenn du in der "for" Zeile aus dem "=" ein "in" machst, sollte es schon fast gehen. Jetzt noch die newfile Zeile aendern (siehe oben) und ich denke, das ist es was du suchst, oder?
nein, mir geht es um um was ganz Anderes. Vergessen wir den kleinen Fehler in der for-Schleife.
Ich möchte
rekursiv die Festplatte nach bestimmten Dateien durchsuchen und den Dateinamen als Argument einem xbeliebigen Programm übergeben.
Du wirst z.B. sehr schnell feststellen, dass so ein Script überhaupt nicht funktionieren wird, sobald in dem Dateinamen Leerzeichen auftreten.
Generell macht man dies mit
find -print0 -name bla ./ | xargs -0 progname
Jetzt stell dir ein Programm vor, das nur eine Datei als Argument bekommen kann. Da muss man sich schon was Neues einfallen lassen. Genau vor so einem Problem stehe ich gerade.
d3 d0 c1 d3 c9 20 cd c9 d2 2c 20 d5 c2 c5 ca 20 d3 c5 c2 d1 0a
-
swar0g
- Beiträge: 289
- Registriert: 12.12.2002 22:07:17
- Wohnort: Hannover
Beitrag
von swar0g » 17.02.2006 19:59:27
Matthias-GE hat geschrieben:Hallo,
von dem = Zeichen mal abgesehen: mit Deinem Befehl änderst Du per sed ja nur die Dateiendung (wenn nicht mehrere Punkte im Dateinamen vorkommen). Wo sind den die Sonderzeichen? Sonderzeichen müssen gegebenenfalls mit sed gequotet werden.
Auch Leerzeichen kannst Du mit sed filtern.
bedeutet: befehl
mv $file $newfile
? (was ja Sinn machen würde)?
Vielleicht solltest Du mal einen repräsentativen (soweit vorhanden) Dateinamen posten.
Gruß
Matthias
z.B. mv
Nehmen wir an, ich habe ich eine CD mit Musikarchiv bekommen. Nun, da sind nur ogg Dateien drin, die fälschlicherweise eine .mp3 Endung bekamen. Unzällige Ordner mit verrücktesten Dateinamen:
blad_blaa blaa'.mp3
blaa_blaa $$$$sososos'''' """".mp3
sosos__???****++**haha.mp3
Es gilt die umzubenennen.
Es ist nur ein Beispielproblem, ich möchte eigentlich keine Dateien umbenennen und ich weiß, das es mächtigere Tools als mv gibt - z.B mmv.
d3 d0 c1 d3 c9 20 cd c9 d2 2c 20 d5 c2 c5 ca 20 d3 c5 c2 d1 0a
-
gms
- Beiträge: 7798
- Registriert: 26.11.2004 20:08:38
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von gms » 17.02.2006 21:00:54
wir erzeugen zwei "schmutzige" Dateien und erstellen eine Funktion "printarg1"
Code: Alles auswählen
gms@gms1:~/tmp/test$ mkdir " dir mit blanks "
gms@gms1:~/tmp/test$ cd " dir mit blanks "/
gms@gms1:~/tmp/test/ dir mit blanks $ touch " file mit blanks "
gms@gms1:~/tmp/test/ dir mit blanks $ touch ' file mit quote " '
gms@gms1:~/tmp/test/ dir mit blanks $ cd ..
gms@gms1:~/tmp/test$ printarg1() { echo $1; }
dann schauen wir uns an was mit "normaler" for-schleife passiert:
Code: Alles auswählen
gms@gms1:~/tmp/test$ for file in $(find -type f -name "*"); do printarg1 "$file"; done
./
dir
mit
blanks
/
file
mit
blanks
./
dir
mit
blanks
/
file
mit
quote
"
mit IFS temporär umgesetzt schauts besser aus:
Code: Alles auswählen
gms@gms1:~/tmp/test$ IFS=$'\n'
gms@gms1:~/tmp/test$ for file in $(find -type f -name "*"); do IFS=" ";printarg1 "$file"; done
./ dir mit blanks / file mit blanks
./ dir mit blanks / file mit quote "
gms@gms1:~/tmp/test$ IFS=" "
mit einer pipe zu einer while schleife schauts auch gut aus:
Code: Alles auswählen
gms@gms1:~/tmp/test$ find -type f -name "*" | while read file; do printarg1 "$file"; done
./ dir mit blanks / file mit blanks
./ dir mit blanks / file mit quote "
Gruß
gms
[edit]
IFS geändert von IFS="" zu IFS=$'\n'
[/edit]
Zuletzt geändert von
gms am 17.02.2006 22:16:18, insgesamt 1-mal geändert.
-
ToPeG
- Beiträge: 437
- Registriert: 14.04.2004 00:42:06
Beitrag
von ToPeG » 17.02.2006 21:15:59
Noch kann es bei "Sonderzeichen" zu Problemen kommen ($& usw.) Wenn man sie auskommentiert umgeht man das.
Code: Alles auswählen
file=`echo $file | sed -e 's/\([^a-zA-Z0-9_-\.~]\)/\\\\\1/g;`
-
gms
- Beiträge: 7798
- Registriert: 26.11.2004 20:08:38
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von gms » 17.02.2006 21:59:05
wieso soll es durch Sonderzeichen zu Problemen kommen:
Code: Alles auswählen
gms@gms1:~/tmp/test$ cd " dir mit blanks "/
gms@gms1:~/tmp/test/ dir mit blanks $ touch ' file mit & '
gms@gms1:~/tmp/test/ dir mit blanks $ touch ' file mit $ '
Code: Alles auswählen
gms@gms1:~/tmp/test$ lsarg1() { ls -ld "$1"; }
gms@gms1:~/tmp/test$ IFS=$'\n'
gms@gms1:~/tmp/test$ for file in $(find -type f -name "*"); do IFS=" ";lsarg1 "$file"; done
-rw-r--r-- 1 gms gms 0 2006-02-17 20:26 ./ dir mit blanks / file mit blanks
-rw-r--r-- 1 gms gms 0 2006-02-17 20:56 ./ dir mit blanks / file mit quote "
-rw-r--r-- 1 gms gms 0 2006-02-17 21:17 ./ dir mit blanks / file mit &
-rw-r--r-- 1 gms gms 0 2006-02-17 21:17 ./ dir mit blanks / file mit $
@swar0g
der IFS im vorhergehenden Posting wurde falsch gesetzt, hier ist er richtig mit IFS=$'\n'
entspricht also dem Newline; und du hast hoffentlich keine Dateien, die ein Newline enthalten
Gruß
gms
-
ToPeG
- Beiträge: 437
- Registriert: 14.04.2004 00:42:06
Beitrag
von ToPeG » 18.02.2006 01:38:46
Weil eine Datei "rm -Rv * > test.txt" zu einem Problem führen könnte wenn man sie in in `` setzt? Sicher wenn man Anführungszeichen verwendet kann man das umgehen, aber nicht immer ist das möglich. (z.B. wenn der Dateiname selbst Anführungszeichen enthält)
-
gms
- Beiträge: 7798
- Registriert: 26.11.2004 20:08:38
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von gms » 18.02.2006 12:58:50
ToPeG hat geschrieben:Weil eine Datei "rm -Rv * > test.txt" zu einem Problem führen könnte wenn man sie in in `` setzt? Sicher wenn man Anführungszeichen verwendet kann man das umgehen, aber nicht immer ist das möglich. (z.B. wenn der Dateiname selbst Anführungszeichen enthält)
Das einzige Sonderzeichne welches hier Probleme machen würde, wäre ein "Newline" und das nur wegen der Zerlegung für die For-Schleife
Weder eine Datei "rm -Rv * >test.txt", noch andere Sonderzeichen die du auch erwähnt hast, wie Anführungszeichen, '$' und '&' führen zu einem Problem:
Code: Alles auswählen
gms@gms1:~/tmp/test$ touch ' dir mit blanks '/'rm -Rv * >test.txt'
gms@gms1:~/tmp/test$ lsarg1() { ls -ld "$1"; }
gms@gms1:~/tmp/test$ IFS=$'\n'
gms@gms1:~/tmp/test$ for file in $(find -type f -name "*"); do IFS=" ";lsarg1 "$file"; done
-rw-r--r-- 1 gms gms 0 2006-02-17 20:26 ./ dir mit blanks / file mit blanks
-rw-r--r-- 1 gms gms 0 2006-02-17 20:56 ./ dir mit blanks / file mit quote "
-rw-r--r-- 1 gms gms 0 2006-02-18 12:50 ./ dir mit blanks / file mit quote '
-rw-r--r-- 1 gms gms 0 2006-02-17 21:17 ./ dir mit blanks / file mit &
-rw-r--r-- 1 gms gms 0 2006-02-17 21:17 ./ dir mit blanks / file mit $
-rw-r--r-- 1 gms gms 0 2006-02-17 22:27 ./ dir mit blanks /- file with minus
-rw-r--r-- 1 gms gms 0 2006-02-18 12:46 ./ dir mit blanks /rm -Rv * >test.txt
Gruß
gms
-
init 0
- Beiträge: 673
- Registriert: 21.10.2003 19:40:28
Beitrag
von init 0 » 18.02.2006 13:06:07
Meiner Meinung nach sollte man irgednwann doch die Bash Geschichten lassen.
Python, Perl, Ruby oder sogar PHP als Scriptsprachen bieten so viele Möglichkeiten.
Ach ja, und nix schrotten.
Ich habe einen schlechten Stil, ich weiss, Danke, wurde mir bereits gesagt.