Verzeichnis in Schleife

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Verzeichnis in Schleife

Beitrag von jhr-online » 01.11.2006 22:24:25

Leute, ihr müsst mir mal kurz unter die Arme greifen...
Ich rufe ein perl-script zur Umwandlung von wma in mp3 auf mit

Code: Alles auswählen

perl meinscript.pl pfad/zum/verzeichnis
Es werden dann alle wma-Dateien in dem Verzeichnis umgewandelt. Alle Verzeichnisse, die ich so bearbeiten möchte, finde ich mit

Code: Alles auswählen

find . -name "*.wma" -printf "%h\n" | uniq
Wie aber bringe ich nun diese von find bzw. uniq erzeugte Liste sinnvoll in eine Schleife der Art

Code: Alles auswählen

for i in `find . -name "*.wma" -printf "%h\n" | uniq`; do perl meinscript.pl $i; done
? So ist's doch nicht richtig, oder?

jhr
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

123456
Beiträge: 6126
Registriert: 08.03.2003 14:07:24

Beitrag von 123456 » 01.11.2006 22:43:45

Code: Alles auswählen

find . -name "*.wma" -printf "%h\n" | uniq | xargs perl meinscript.pl
vielleicht...?

ps: aber Vorsicht....ist nur Theorie...

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 01.11.2006 22:55:16

Die Idee ist nicht doof, ganz im Gegenteil, aber außer der Schlusszeile "Fertig" brachte mir das script nichts produktives; nicht mal Fehlermeldungen... :D

jhr
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

123456
Beiträge: 6126
Registriert: 08.03.2003 14:07:24

Beitrag von 123456 » 01.11.2006 23:14:06

jhr-online hat geschrieben:Die Idee ist nicht doof, ganz im Gegenteil, aber außer der Schlusszeile "Fertig" brachte mir das script nichts produktives; nicht mal Fehlermeldungen... :D
Irgendwie sollte das so gehen....
vielleicht das "-printf "%h\n" durch "-print" ersetzen.

EDIT:
vielleicht auch den Pfad zum Perl ausschreiben....

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 01.11.2006 23:23:30

-print gibt auch den Dateinamen aus... Ich brauche aber NUR das Verzeichnis, daher -printf usw.

jhr
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 01.11.2006 23:46:01

Code: Alles auswählen

find . -name "*.wma" -printf "%h\n" | uniq | xargs -0 perl meinscript.pl
So geht's anscheinend... Danke ub13 (und herrchen im Chat)! Ich hab ne Lösung... :)

jhr
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 03.11.2006 00:08:01

Stimmt nicht... der Testlauf war nicht aussagekräftig... Der Fehler scheint wohl da zu liegen, dass -printf von find kein Nullbyte liefern kann. Also kann xargs nichts vernünftiges übergeben... Ideen?

jhr
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

123456
Beiträge: 6126
Registriert: 08.03.2003 14:07:24

Beitrag von 123456 » 03.11.2006 10:52:49

jhr-online hat geschrieben:Stimmt nicht... der Testlauf war nicht aussagekräftig... Der Fehler scheint wohl da zu liegen, dass -printf von find kein Nullbyte liefern kann. Also kann xargs nichts vernünftiges übergeben... Ideen?
Hmmh. Das sollte eigentlich durch das "-0" gehandelt werden. Siehe "man xargs".

Dann schreib Dir doch ein Skript - dort schreibst Du den Output erstmal in ein File oder Array und arbeitest das dann mit einer for Schleife ab. (ok, ist etwas umständlich...)

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 03.11.2006 11:08:09

ub13 hat geschrieben:Hmmh. Das sollte eigentlich durch das "-0" gehandelt werden. Siehe "man xargs".
Naja klar, aber printf übergibt kein Nullbyte, sodass xargs keins findet...
Dann schreib Dir doch ein Skript - dort schreibst Du den Output erstmal in ein File oder Array und arbeitest das dann mit einer for Schleife ab. (ok, ist etwas umständlich...)
Darauf läuft's wohl hinaus... Also wieder lesen: Arrays in einer Shell...

jhr
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

123456
Beiträge: 6126
Registriert: 08.03.2003 14:07:24

Beitrag von 123456 » 03.11.2006 11:14:39

...dann noch ne Idee. Du nimmst anstelle printf - print und cuttest (am Ende der print Zeile) ab dem letzten Slash alles weg.

Aber ob das einfacher ist? ;)

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 03.11.2006 11:20:05

Das war ehrlich gesagt mein erster Gedanke, aber ich habe nicht rausgefunden, ob - und wenn, dann wie - ich cut beibringen kann, alles vor dem letzten / auszugeben, da ich irgendwie die Delimiter nicht von hinten zählen kann.

jhr
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

123456
Beiträge: 6126
Registriert: 08.03.2003 14:07:24

Beitrag von 123456 » 03.11.2006 11:25:11

jhr-online hat geschrieben:Das war ehrlich gesagt mein erster Gedanke, aber ich habe nicht rausgefunden, ob - und wenn, dann wie - ich cut beibringen kann, alles vor dem letzten / auszugeben, da ich irgendwie die Delimiter nicht von hinten zählen kann.
"cut" könnte funktionieren, wenn wie in "einem" Verzeichnis die Einträge gleich lang sind. Mit dem Deliiter "/" zerlegst Du den String und mit "-f No" - No ist der xte Parameter hast Du es. Aber der find geht ja rekursiv über die Verzeichnisse...

Vielleicht wäre "sed" eine Option?

123456
Beiträge: 6126
Registriert: 08.03.2003 14:07:24

Beitrag von 123456 » 03.11.2006 11:40:58

Code: Alles auswählen

find . -name "*.wma" -printf "%h\n" | uniq > file
while read line ; do
   perl meinscript.pl  $line
done < file
...sollte für ein Skript ausreichen. Ob die Syntax ok ist, musst Du ausprobieren...

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 03.11.2006 11:52:24

Müsste es dann nicht auch so in einer Zeile gehen?

Code: Alles auswählen

while read line; do perl script.ol $line; done < `find . -name "*.wma" -printf "%h\n" | uniq`
jhr

//edit: Nein, geht nicht, weil der redirect so nicht funktioniert. Und interessanterweise geht auch deine Scriptlösung nicht, weil wieder blödsinn überliefert wird... Gleich mehr dazu - bleiben Sie dran!
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

123456
Beiträge: 6126
Registriert: 08.03.2003 14:07:24

Beitrag von 123456 » 03.11.2006 13:03:38

vielleicht hängt das mit dem aktuellen Verzeichnis "." zusammen, durch printf hervorgerufen?

hier ein Vorschlag:

Code: Alles auswählen

find . -name "*.wma" -printf "%h\n" | uniq > file 
while read line ; do 
   if [ $line = "." ]; then
        break
   fi
   perl meinscript.pl  $line 
done < file

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 03.11.2006 14:55:00

Ich werd's ganz anders machen, dachte ich mir vorhin, dann wird's einfacher... Naja, es tut nicht - war klar!

Die Idee: Ein Script, das alle wma findet und die erstmal komplett in ein Array schreibt. Dazu lasse ich find zeilenweise den kompletten Pfad ausgeben und dann das Array zeilenweise füllen. Die Weiterbearbeitung mit dem Array folgt, sobald ich was ins Array kriege, denn das geht schon schief.

Code: Alles auswählen

PATH="/home/jhr/musik"
FIND="/usr/bin/find"
declare -a ARRAY
COUNTER=0
echo "`$FIND $PATH -name \"*.wma\" -printf \"%p\n\"`" | while read line
do
        echo "$COUNTER = $line"
        ARRAY[$COUNTER]=$line
        let COUNTER=$COUNTER+1
done
Die echo-Zeile gibt mir z.B. brav aus:

Code: Alles auswählen

375 = /home/jhr/musik/geilepartymucke/fetziges lied.wma
Wenn ich aber den Inhalt des Arrays ausgeben lasse, kommt nix, also ist wohl auch nix drin... Warum?

jhr
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

123456
Beiträge: 6126
Registriert: 08.03.2003 14:07:24

Beitrag von 123456 » 03.11.2006 15:19:27

wie gibst Du denn das Array aus?

EDIT:
${ARRAY[$COUNTER]}

sollte eigentlich was ausgeben...

jhr-online
Beiträge: 2186
Registriert: 18.09.2005 15:52:02
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Beitrag von jhr-online » 03.11.2006 15:58:31

Okay, im Array war was drin und ich zu doof dafür... Ich habe es jetzt ohne Array gemacht und bin zu folgender Lösung gekommen:

Code: Alles auswählen

PATH="/home/jhr/musik"
WHATTOCONVERT="*.wma"

FIND="/usr/bin/find"
LINE="/usr/bin/line"
DIRNAME="/usr/bin/dirname"
BASENAME="/usr/bin/basename"
MPLAYER="/usr/bin/mplayer"
OGGENC="/usr/bin/oggenc"
RM="/bin/rm"

echo "`$FIND $PATH -name \"$WHATTOCONVERT\" -printf \"%p\n\"`" | while read line
do
        DIR=`$DIRNAME "$line"`
        FILEFULL=`$BASENAME "$line"`
        FILELENGTH=${#FILEFULL}-4
        FILE=${FILEFULL:0:$FILELENGTH}
        echo "new directory: $DIR"
        echo "converting $FILEFULL to $FILE.wav"
        $MPLAYER "$DIR/$FILEFULL" -quiet -vc null -vo null -ao pcm:file="$DIR/$FILE.wav"
        echo "converting $FILE.wav to $FILE.ogg"
        $OGGENC "$DIR/$FILE.wav" -Q -o "$DIR/$FILE.ogg"
        echo "Removing needless wav and wma files..."
        $RM "$DIR/$FILEFULL"
        $RM "$DIR/$FILE.wav"
        echo "Done."
done
exit 0
Das scheint derzeit zu funktionieren...

jhr

//edit: GPLv2 :D
Desktop: Intel Core2Quad Q8300 2.5GHz, 256GB SSD + 1 TB HDD, 8 GB RAM, Debian Sid, Kernel 3.13

Antworten