Folgendes: Ich habe ein Verzeichnis, das ich innerhalb eines Skriptes ausgeben moechte, nummeriert. Das ist soweit kein Problem:
cd $DIR
N=1
for FILE in *; do
echo "${N}"'. '"${FILE}"
N=`expr ${N} + 1`
done
echo -n "Ihre Wahl: "; read EINGABE
Problem ist nun, wie kann ich eine Auswahl erzeugen. Also das z.B. eine "2" als Wert fuer EINGABE auch zu der dazugehoerigen Datei referenziert wird ? Geht das ohne Arrays ueberhaupt ?
Mit waere das kein Problem, wuerde aber bash unabdingabr machen.
DATEI[${N}]=${FILE}
Gibt es eine sh kompatible Moeglichkeit ?
Urspruenglich hatte ich den Namen der Datei als Eingabe erwartet und auf Gueltigkeit ueberprueft. Wird aber auf Dauer zu aufwendig. Und zu Bedienerunfreundlich.
bash: Kreieren eine nummerierten Auswahlliste
Re: bash: Kreieren eine nummerierten Auswahlliste
hast Du mal an die Verwendung von "dialog" gedacht ?
<!--http--><a href="http://www.hightek.org/dialog/" target="_blank"> http://www.hightek.org/dialog/ </a><!--url-->
<!--http--><a href="http://www.hightek.org/dialog/" target="_blank"> http://www.hightek.org/dialog/ </a><!--url-->
Last edited by burni2 on 13. Feb 2003 20:29, edited 1 time in total.
Re: bash: Kreieren eine nummerierten Auswahlliste
Ja. Aber Danke fuer die Hilfe. Dialog kommt zum Schluss, wenn der Rest steht. Oder wird durch getopt(1) ersetzt.
Stolpere momentan von einem Problem ins naechste. Moechte mich momentan nicht noch in etwas ausserhalb von sh einarbeiten. Zumal ich vermute, das eine Referenzierung ausserhalb von Dialog erfolgt und Dialog "nur" die Darstellung uebernimmt. Wie gesagt, nur eine Vermutung, kann mich auch taeuschen.
Stolpere momentan von einem Problem ins naechste. Moechte mich momentan nicht noch in etwas ausserhalb von sh einarbeiten. Zumal ich vermute, das eine Referenzierung ausserhalb von Dialog erfolgt und Dialog "nur" die Darstellung uebernimmt. Wie gesagt, nur eine Vermutung, kann mich auch taeuschen.
Re: bash: Kreieren eine nummerierten Auswahlliste
So aus der Hand würden mir (ausser der Verwendung von bash/ksh <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle">) zwei Möglichkeiten einfallen, mittels reinen sh-Mitteln zum Ziel zu kommen.
1. Mittels eval kann man Variablennamen dynamisch bauen, was sich ungefähr so wie Arrays nutzen lässt. Nur ist dann die Syntax ziemlich haarig:<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">cd $DIR
N=1
for FILE in *; do
echo "${N}"'. '"${FILE}"
N=`expr ${N} + 1`
eval 'FILE_'${N}'=${FILE}'
done
echo -n "Ihre Wahl: "; read EINGABE
eval 'AUSWAHL=${FILE_'${EINGABE}'}'
echo "Ausgewählte Datei: ${AUSWAHL}"
</font><hr></pre></blockquote>
eval bewirkt, dass die Shell alle Ersetzungen einmal vornimmt, bevor das Endergebnis so behandelt wird, als wäre es frisch eingelesen worden. Aus der Zeile<pre>eval 'FILE_'${N}'=${FILE}'</pre> wird für N=1 die Zeile <pre>FILE_1=${FILE}</pre> und damit in die frisch zusammenbegastelte Variable FILE_1 der Wert der aktuellen Datei geschrieben. Für N=2 wird <pre>FILE_2=${FILE}</pre> draus usw.
Bastel mal ein bisschen damit; der Umgang mit eval erschliesst sich nur durch Übung. Das ist so eines von den Kommandos, bei denen man sich ewig fragt, wöfür sie gut sein sollen, bis man dann mal so eine Lösung sieht... <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle">
Die zweite Variante poste ich später.
Jochen
1. Mittels eval kann man Variablennamen dynamisch bauen, was sich ungefähr so wie Arrays nutzen lässt. Nur ist dann die Syntax ziemlich haarig:<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">cd $DIR
N=1
for FILE in *; do
echo "${N}"'. '"${FILE}"
N=`expr ${N} + 1`
eval 'FILE_'${N}'=${FILE}'
done
echo -n "Ihre Wahl: "; read EINGABE
eval 'AUSWAHL=${FILE_'${EINGABE}'}'
echo "Ausgewählte Datei: ${AUSWAHL}"
</font><hr></pre></blockquote>
eval bewirkt, dass die Shell alle Ersetzungen einmal vornimmt, bevor das Endergebnis so behandelt wird, als wäre es frisch eingelesen worden. Aus der Zeile<pre>eval 'FILE_'${N}'=${FILE}'</pre> wird für N=1 die Zeile <pre>FILE_1=${FILE}</pre> und damit in die frisch zusammenbegastelte Variable FILE_1 der Wert der aktuellen Datei geschrieben. Für N=2 wird <pre>FILE_2=${FILE}</pre> draus usw.
Bastel mal ein bisschen damit; der Umgang mit eval erschliesst sich nur durch Übung. Das ist so eines von den Kommandos, bei denen man sich ewig fragt, wöfür sie gut sein sollen, bis man dann mal so eine Lösung sieht... <img src="http://www.pl-forum.de/UltraBoard/Images/Happy.gif" border="0" align="middle">
Die zweite Variante poste ich später.
Jochen
Re: bash: Kreieren eine nummerierten Auswahlliste
Wow. Nicht, das ich eval jetzt aus dem Stegreif benutzen koennte, aber es klappt. Wenn auch zugegebenermassen einfach abgeschrieben.
Was mich allerdings recht konfus macht, ist die Verwendung der einfachen Hochkommata '
Eigentlich sollten die doch genau _nicht_ interpretieren. echo '${HOME}' gibt auch ${HOME} aus statt /home/joe.
Ich erinnere mich noch aus einem anderen Posting mit expr an eine aehnliche Situation:
VAR=`expr "${STRING} : '[a-z]*'`
Man sollte eigentlich meinen, das der regulaere Ausdruck interpretiert werden sollte, oder ? expr soll ja nicht nach der Kette '[a-z]' suchen, sondern nach dem, was [a-z] interpretiert.
Wie dem auch sei, die obligatorische Danksagung soll nicht fehlen. Vielleicht solltest Du mal ueberlegen, kommerziellen Support auf Steuerklasse 6 bei Pro-Linux machen
Was mich allerdings recht konfus macht, ist die Verwendung der einfachen Hochkommata '
Eigentlich sollten die doch genau _nicht_ interpretieren. echo '${HOME}' gibt auch ${HOME} aus statt /home/joe.
Ich erinnere mich noch aus einem anderen Posting mit expr an eine aehnliche Situation:
VAR=`expr "${STRING} : '[a-z]*'`
Man sollte eigentlich meinen, das der regulaere Ausdruck interpretiert werden sollte, oder ? expr soll ja nicht nach der Kette '[a-z]' suchen, sondern nach dem, was [a-z] interpretiert.
Wie dem auch sei, die obligatorische Danksagung soll nicht fehlen. Vielleicht solltest Du mal ueberlegen, kommerziellen Support auf Steuerklasse 6 bei Pro-Linux machen
Re: bash: Kreieren eine nummerierten Auswahlliste
> Eigentlich sollten die doch genau _nicht_ interpretieren. echo '${HOME}' gibt auch ${HOME} aus statt /home/joe.
Und das ist auch vollkommen korrekt, wie Dein Beispiel ja auch beweist. Nur dass durch eval jetzt die Shell die Zeile zweimal bearbeitet und die Apostrophen nach dem ersten Mal bereits verschwunden sind. Am Beispiel gezeigt (mit V=1 und X=2):<pre>eval 'VAR_'$V'=$X'</pre>Bevor die Shell jetzt ein Kommando aufrufen kann, muss die die diversen Ersetzungen durchführen wie Variablenersetzung, usw. Ausserdem wird das Quoting beachtet, d.h. die Zeichenketten in '...' bleiben unverändert. Zum Schluss will die Shell also folgendes Kommando aufrufen:<pre>eval VAR_1=$X</pre>Die Apostrophe wurden ja beachtet und abgearbeitet, also weg damit. eval sagt der Shell nun, sie soll den ganzen Vorgang mit Variablenersetzung, Quoting usw. <i>noch einmal</i> auf die Argumente zu eval anwenden und diese dann erst ausführen. Die Shell geht also wieder hin - kein Quoting mehr, also $X durch 2 ersetzen. Auszuführen ist dann<pre>VAR_1=2</pre>Und das passiert denn auch und die Variable VAR_1 wird auf den Wert 2 gesetzt.
> Man sollte eigentlich meinen, das der regulaere Ausdruck interpretiert werden sollte, oder ? expr soll ja nicht nach der Kette '[a-z]' suchen, sondern nach dem, was [a-z] interpretiert.
Aber selbstverständlich soll er das! Du würfelst nur die Shell und expr durcheinander. In <pre>VAR=`expr "${STRING}" : '[a-z]*'`</pre>wird ja erst einmal<pre>expr "${STRING}" : '[a-z]*'</pre>ausgeführt und dessen Ausgabe dort eingesetzt, wo das Kommando stand. Also Variablenersetzung und Quoting ausführen. expr wird dementsprechend so aufgerufen:<pre>expr Inhalt_von_STRING : [a-z]*</pre>Die Shell geht an den Regulären Ausdruck nicht ran, weil er in Apostrophen eingeschlossen ist. expr wiederum weiss, dass er beim Doppelpunkt-Operator das dritte Argument als Regexp interpretieren soll und tut das dann auch. Hätten die Apostrophe um den Regexp gefehlt, hätte dort die Shell probiert, Dateinamen einzusetzen, die (im aktuellen Verzeichnis) mit einen Kleinbuchstaben beginnen, gefolgt von beliebig vielen beliebigen Zeichen.
Du weist also die Shell mit den Apostrophen an, bestimmte Zeichenfolgen in Ruhe zu lassen und 1:1 an das zu startende Kommando zu übergeben. Was dieses nun wiederum damit macht, ist der Shell völlig egal.
> Vielleicht solltest Du mal ueberlegen, kommerziellen Support auf Steuerklasse 6 bei Pro-Linux machen
Ach, ich freue mich immer, wenn ich weiterhelfen kann. Skripten kann ich ganz gut und ein paar Sachen weiss ich schon über Linux, das kann man weitergeben als Dankeschön für dieses tolle Betriebssystem. Ausserdem kann ich so meine oberlehrerhafte Seite mal so richtig raushängen lassen! <img src="http://www.pl-forum.de/UltraBoard/Images/Wilk.gif" border="0" align="middle">
Jochen
Und das ist auch vollkommen korrekt, wie Dein Beispiel ja auch beweist. Nur dass durch eval jetzt die Shell die Zeile zweimal bearbeitet und die Apostrophen nach dem ersten Mal bereits verschwunden sind. Am Beispiel gezeigt (mit V=1 und X=2):<pre>eval 'VAR_'$V'=$X'</pre>Bevor die Shell jetzt ein Kommando aufrufen kann, muss die die diversen Ersetzungen durchführen wie Variablenersetzung, usw. Ausserdem wird das Quoting beachtet, d.h. die Zeichenketten in '...' bleiben unverändert. Zum Schluss will die Shell also folgendes Kommando aufrufen:<pre>eval VAR_1=$X</pre>Die Apostrophe wurden ja beachtet und abgearbeitet, also weg damit. eval sagt der Shell nun, sie soll den ganzen Vorgang mit Variablenersetzung, Quoting usw. <i>noch einmal</i> auf die Argumente zu eval anwenden und diese dann erst ausführen. Die Shell geht also wieder hin - kein Quoting mehr, also $X durch 2 ersetzen. Auszuführen ist dann<pre>VAR_1=2</pre>Und das passiert denn auch und die Variable VAR_1 wird auf den Wert 2 gesetzt.
> Man sollte eigentlich meinen, das der regulaere Ausdruck interpretiert werden sollte, oder ? expr soll ja nicht nach der Kette '[a-z]' suchen, sondern nach dem, was [a-z] interpretiert.
Aber selbstverständlich soll er das! Du würfelst nur die Shell und expr durcheinander. In <pre>VAR=`expr "${STRING}" : '[a-z]*'`</pre>wird ja erst einmal<pre>expr "${STRING}" : '[a-z]*'</pre>ausgeführt und dessen Ausgabe dort eingesetzt, wo das Kommando stand. Also Variablenersetzung und Quoting ausführen. expr wird dementsprechend so aufgerufen:<pre>expr Inhalt_von_STRING : [a-z]*</pre>Die Shell geht an den Regulären Ausdruck nicht ran, weil er in Apostrophen eingeschlossen ist. expr wiederum weiss, dass er beim Doppelpunkt-Operator das dritte Argument als Regexp interpretieren soll und tut das dann auch. Hätten die Apostrophe um den Regexp gefehlt, hätte dort die Shell probiert, Dateinamen einzusetzen, die (im aktuellen Verzeichnis) mit einen Kleinbuchstaben beginnen, gefolgt von beliebig vielen beliebigen Zeichen.
Du weist also die Shell mit den Apostrophen an, bestimmte Zeichenfolgen in Ruhe zu lassen und 1:1 an das zu startende Kommando zu übergeben. Was dieses nun wiederum damit macht, ist der Shell völlig egal.
> Vielleicht solltest Du mal ueberlegen, kommerziellen Support auf Steuerklasse 6 bei Pro-Linux machen
Ach, ich freue mich immer, wenn ich weiterhelfen kann. Skripten kann ich ganz gut und ein paar Sachen weiss ich schon über Linux, das kann man weitergeben als Dankeschön für dieses tolle Betriebssystem. Ausserdem kann ich so meine oberlehrerhafte Seite mal so richtig raushängen lassen! <img src="http://www.pl-forum.de/UltraBoard/Images/Wilk.gif" border="0" align="middle">
Jochen