bash: Kreieren eine nummerierten Auswahlliste

Post Reply
Message
Author
drake

bash: Kreieren eine nummerierten Auswahlliste

#1 Post by drake »

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.

burni2
Posts: 12
Joined: 01. Feb 2003 12:03
Location: Aachen
Contact:

Re: bash: Kreieren eine nummerierten Auswahlliste

#2 Post by burni2 »

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-->
Last edited by burni2 on 13. Feb 2003 20:29, edited 1 time in total.

Drake

Re: bash: Kreieren eine nummerierten Auswahlliste

#3 Post by Drake »

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.

Jochen

Re: bash: Kreieren eine nummerierten Auswahlliste

#4 Post by Jochen »

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

drake

Re: bash: Kreieren eine nummerierten Auswahlliste

#5 Post by drake »

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 ;)

Jochen

Re: bash: Kreieren eine nummerierten Auswahlliste

#6 Post by Jochen »

> 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

Post Reply