Script: Befehl für jede Datei in einem Verzeichnis ausführen

Du suchst ein Programm für einen bestimmten Zweck?
Antworten
Benutzeravatar
npi
Beiträge: 567
Registriert: 03.08.2003 17:52:10

Script: Befehl für jede Datei in einem Verzeichnis ausführen

Beitrag von npi » 05.09.2003 11:22:41

Hi,
ich möchte in ein Script einbauen, dass er für jede Datei in einem Verzeichnis, die ein .ogg hintendran hat, einen Befehl ausführt, nämlich diese Datei in mp3 konvertieren.
Um die Datei zu konvertieren benutz ich sox und lame also so:

Code: Alles auswählen

sox datei.ogg datei.wav
lame -v -t datei.wav datei.mp3
Jetzt brauch ich nur noch irgendwie eine Schleife, die mir das für jede Datei im Verzeichnis ausführt. Das Problem ist, dass die Dateien natürlich ganz unterschiedliche Namen ohne fortlaufende Nummern haben.
Weiss jemand von euch wie ich das in das Script reinbaue?

npi

P.S.: Kann man die konvertierung eigentlich irgendwie über eine Pipe in eine Zeile schreiben?

zaarkov
Beiträge: 123
Registriert: 14.08.2003 11:08:51

Beitrag von zaarkov » 05.09.2003 11:55:30

wege gibt's spontan min. 3
die einfachste variante, die mir grad' durch 'n kopf geht
is' sowas wie:

mach dir aus deinem sox/lame ein ogg_mp3-skript, welches
als argument das ogg nimmt
dann:

Code: Alles auswählen

find verzeichnis -name *.ogg -print0 |xargs -0 ogg_mp3
wobei verzeichnis das oberste musik-verzeichnis ist.

das kann man natuerlich auch noch verfeinern, aber so sieht das geruest aus.

zaarkov

PS: das is' macht's natuerlich rekursiv
Zuletzt geändert von zaarkov am 05.09.2003 16:04:59, insgesamt 1-mal geändert.

Benutzeravatar
atithi
Beiträge: 37
Registriert: 11.08.2003 00:00:28

Beitrag von atithi » 05.09.2003 13:25:08

for n in *.ogg; do sox $n $n.wav; done
for n in *.wav; do lame -v -t $n $n.mp3; done

ist allerdings ungetestet ;-)

Benutzeravatar
npi
Beiträge: 567
Registriert: 03.08.2003 17:52:10

Beitrag von npi » 06.09.2003 00:20:48

Ok, das mit der Schleife von atithi klapp schon mal fast so wie ich mir das vorgestellt habe(die variante von zaarkof hab ich noch nicht probiert, hört sich zwar gut an aber ich hab keine ahnung, wie man ein skript argumente entgegennehmen lässt), allerdings hab ich mehrere Probleme.

1. wenn der Dateiname Leerzeichen enthält, dann schneidet sox das argument nach dem leerzeichen ab, und mekert dann natürlich, dass er die datei nicht findet(normalerweise hat man ja einen backslash vor jedem leerzeichen um zu erkennen, dass der dateiname weitergeht, aber da irgendwie nicht).

2. hat die Datei am Schluss dann drei endungen und heisst dann .ogg.wav.mp3 was ich natürlich möglichst auch nicht will. Ich nehm mal an dass man dass mit ein paar stringmanipulationen machen kann aber da dies so ungefähr mein erstes skript ist, dass nicht nur programme der reihe nach aufruft, weiss ich nicht wie ich zum Beispiel die länge eines strings rausfinde oder teile davon kopiere bzw. abschneide.

danke noch mal für die Bemühungen,

npi

zaarkov
Beiträge: 123
Registriert: 14.08.2003 11:08:51

Beitrag von zaarkov » 06.09.2003 00:52:42

parameter kannst du in shell-skripten mittels "$1"..."$n" benutzen.

meine version sollte dabei auch mit den blanks umgehen koennen.

zaarkov

Chimerer
Beiträge: 514
Registriert: 28.01.2002 16:10:44

Beitrag von Chimerer » 06.09.2003 10:50:12

@npi:

1. damit das funktioniert musst du den internal field seperator auf "" setzen.

2. Das liegt daran das er die Suffixe einfach mit übernimmt.

So sollte auch diese Variante funtkionieren:

Code: Alles auswählen

#!/bin/sh

IFS=""

for n in *.ogg; do sox $n `basename $n ogg`wav; done 
for n in *.wav; do lame -v -t $n `basename $n wav`mp3; done 

rm *.ogg *.wav

Benutzeravatar
npi
Beiträge: 567
Registriert: 03.08.2003 17:52:10

Beitrag von npi » 06.09.2003 15:03:08

So, mein skript sieht jetzt so aus, fürs debuggen hab ich nur die zeilen in denen wiklich was an Dateien gemacht wird auskommentiert:

Code: Alles auswählen

#! /bin/sh
# ogg2mp3 - Konvertiert eine .ogg datei nach mp3 benötigt sox und lame
# Gebrauch: ogg2mp3 QUELLVERZEICHNIS ZIELVERZEICHNIS

IFS=""

if [ "$1" = "" ];
then
   echo "Gebrauch: ogg2mp3 QUELLVERZEICHNIS ZIELVERZEICHNIS";
   exit;
fi

if [ "$2" = "" ];
then
   echo "Gebrauch: ogg2mp3 QUELLVERZEICHNIS ZIELVERZEICHNIS";
   exit;
fi

# in der nächsten zeile sollte möglichst vor dem Beenden noch eine Fehlermeldung ausgegeben werden
test -d $1 || exit;
test -d $2 || mkdir $2;


cd $1 || exit;
for n in *.ogg;
do
   echo "Konvertiere "$n" nach "`basename $n .ogg`".wav";
#   sox $n /tmp/`basename $n .ogg`.wav;
done

cd /tmp || exit;
for n in *.wav;
do
   echo "Konvertiere "$n" nach "`basename $n .wav`".mp3";
#   lame -v -t $n $2`basename $n .wav`.mp3;
   echo "Lösche $n";
#   rm $n;
done
jetzt würd ich gerne noch ein paar sachen verschönern:

1. nach dem test ob der erste parameter ein Verzeichnis ist (Z.20) würde ich gerne erst noch vor dem Verlassen eine Fehlermeldung ausgeben lassen, ich hab mal:

Code: Alles auswählen

test -d $1 || echo $1" ist kein Verzeichnis!" && exit;
ausprobiert, aber dann verlässt er das skript irgendwie immer an dieser stelle und mit klammern also so:

Code: Alles auswählen

test -d $1 || (echo $1" ist kein Verzeichnis!" && exit);
funzts auch nicht

2. in dieser:

Code: Alles auswählen

test -d $2 || mkdir $2;
Zeile würde ich gerne noch den benutzer fragen, ob auch wirklich ein verzeichnis angelegt werden soll.

3. kann man die if abfrage für beide parameter gleichzeitig machen, also beide bedingungen mit or verknüpfen?
ich hab mal

Code: Alles auswählen

if [ "$1" = "" || "$2" = "" ];
ausprobiert, aber da stimmt wohl was an der syntax nicht


ich hoffe, dass ihr mir auch hier helfen werdet,

thx
npi

P.S.: ist es eigentlich egal, ob man das skript mit bash oder mit sh ausführen lässt. also ob die erste zeile #! /bin/bash oder #! /bin/sh heisst?
wann braucht man eigentlich ein semikolon am ende der zeile und wann kann man es weglassen?

Chimerer
Beiträge: 514
Registriert: 28.01.2002 16:10:44

Beitrag von Chimerer » 06.09.2003 16:18:52

1.

Code: Alles auswählen

if  [ ! -d $1 ] 
then
	echo "$1 ist kein Verzeichnis"
	exit 1
fi
2.

Code: Alles auswählen

if [ ! -d $2 ]
then
	read -s -n 1 -p "Verzeichnis $2 anlegen? Y/N" check
		
		if [ "$check" = "y" ]
		then
			mkdir $2	
		else				
			exit 1
		fi
		
fi
3.

Code: Alles auswählen

if [ "$1" = "" -o "$2" = "" ] 
PS: /bin/sh ist normalerweise ein Link auf /bin/bash, ist also egal. Das Semikolon braucht man nur wenn danach in der gleichen Zeile noch ein Befehl stehen soll.

Benutzeravatar
npi
Beiträge: 567
Registriert: 03.08.2003 17:52:10

Beitrag von npi » 07.09.2003 18:39:45

Es ist vollbracht, :D
das Script funktioniert jetzt so wie es soll, vielen Dank, das ihr mir so gut geholfen habt.
Hier nochmal das fertige Script, vielleicht kann es nochmal jemand brauchen:

Code: Alles auswählen

#! /bin/sh
# ogg2mp3 - Konvertiert alle .ogg dateien in einem Verzeichnis nach mp3. Benötigt sox und lame
# Gebrauch: ogg2mp3 QUELLVERZEICHNIS ZIELVERZEICHNIS

IFS=""

if [ "$1" = "" -o "$2" = "" ];
then
   echo "Gebrauch: ogg2mp3 QUELLVERZEICHNIS ZIELVERZEICHNIS";
   exit;
fi

if [ ! -d $1 ];
then
   echo "$1 ist kein Verzeichnis! Verlasse das Programm";
   exit 1;
fi

if [ ! -d $2 ];
then
   read -s -n 1 -p "Verzeichnis $2 ist nich vorhanden, soll es angelegt werden? [y/n]" check;
   if [ "$check" = "y" ];
   then
      mkdir $2;
      echo "Verzeichnis $2 wurde angelegt";
   else
      echo "Verlasse das Programm!";
      exit 1;
   fi
fi


cd $1 || exit;
for n in *.ogg;
do
   echo "Konvertiere "$n" nach "`basename $n .ogg`".wav";
   sox $n /tmp/`basename $n .ogg`.wav;
done

cd /tmp || exit;
for n in *.wav;
do
   echo "Konvertiere "$n" nach "`basename $n .wav`".mp3";
   lame -v -t $n $2/`basename $n .wav`.mp3;
   echo "Lösche $n";
   rm $n;
done
npi

Antworten