uboat
Anmeldungsdatum: 23. Juni 2009
Beiträge: 178
|
Ich möchte eine Variable anhand eines Prefixes auslesen. Das klappt auch. Allerdings bekomme ich eine Fehlermeldung, wenn ich den Prefix nicht direkt, sondern per Variable angebe: | prefix_variable=HelloWorld # Variable zum auslesen.
echo ${!prefix_*}; # Auslesen der Variable prefix_variable per prefix "prefix_"
prefix=prefix_ # Prefix "prefix_" in Variable prefix speichern.
echo ${!$prefix*} # Auslesen der Variable prefix_variable.
bash: ${!$prefix*}: bad substitution
|
Wie ist die korrekte Syntax für die letzte Zeile? uboat
|
uboat
(Themenstarter)
Anmeldungsdatum: 23. Juni 2009
Beiträge: 178
|
In der Manpage finde ich lediglich:
${!prefix*}
${!prefix@}
Names matching prefix. Expands to the names of variables whose
names begin with prefix, separated by the first character of the
IFS special variable. When @ is used and the expansion appears
within double quotes, each variable name expands to a separate
word.
Warum ich prefix nicht als generische Variable angeben kann bleibt mir unklar. Ich könnte mir den String mit dem Prefix aus der Variable zusammenbauen und dann per eval ausführen, hoffe aber, dass es eine andere Lösung gibt.
| x='${!'$prefix'*}'
eval echo $x
|
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Du müsstest vielleicht mal verraten, was Du erwartest, bzw. was Du genau vorhast. Bei mir geht es jedenfalls durchaus: track@track:~$ xy=1 # 1. Variable
track@track:~$ echo ${!xy*} # Parameter Expansion: zeigt die 1. Variable
xy
track@track:~$ xyz=2 # 2. Variable
track@track:~$ echo ${!xy*} # Parameter Expansion: zeigt die 1. und 2. Variable
xy xyz
track@track:~$ xy_=${!xy*} # 3. Variable: gesetzt mit dem Ergebnis der Parameter Expansion
track@track:~$ echo ${!xy*} # Parameter Expansion: zeigt alle 3 Variablen
xy xy_ xyz
track@track:~$ echo $xy_ # Inhalt der 3. Variablen ist natürlich nur die 1. und 2. Variable
xy xyz Was macht er bei Dir anders ? track
|
uboat
(Themenstarter)
Anmeldungsdatum: 23. Juni 2009
Beiträge: 178
|
@track: Ich kann versuchen es anders zu formulieren, wenn es nicht verständlich war. Als Kurzversion möchte ich, dass echo ${!$myprefix*} keinen Fehler bringt, sondern alle Variablen mit dem Prefix ausgibt, den ich vorher über die Variable myprefix gesetzt habe (siehe Beispielcode Post 1, Zeile 3 bis 4). Bei deinem Beispiel verwendest du keine Variable sondern gibst den Prefix direkt als String Literal an. Dass das funktioniert hatte ich in meinem ersten Post geschrieben (siehe Beispielcode Post 1, Zeile 1 bis 2).
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Ach so, Du möchtest nicht die Variablennamen, sondern die Variableninhalte sehen ...? Das könntest Du z.B. mit einer for- Schleife machen: track@track:~$ xy=1
track@track:~$ xyz=2
track@track:~$ xy_=${!xy*}
track@track:~$ echo ${!xy*}
xy xy_ xyz
track@track:~$ for i in ${!xy*} ; do
> echo "${!i}"
> done
1
xy xyz
2 Oder evt. mit declare -n wie es hier vorgeschlagen wird. Mit eval ginge es auch, aber davon würde ich dringend abraten, wegen der damit verbundenen Sicherheitslecks. Edit: Eine andere saubere Alternative wären assoziative Arrays: track@track:~$ declare -A a
track@track:~$ a[yz]=x1
track@track:~$ a[yza]=x2
track@track:~$ a[yz_]=Buuuuuuh
track@track:~$ echo ${a[*]}
x1 Buuuuuuh x2
track@track:~$ x[7]=yza # Du siehst, Array-Indizes sind sogar verschachtelbar:
track@track:~$ n=7
track@track:~$ echo ${x[n]}
yza
track@track:~$ echo ${a[${x[n]}]}
x2
LG,
track
|
uboat
(Themenstarter)
Anmeldungsdatum: 23. Juni 2009
Beiträge: 178
|
Hallo track, Danke für deine Antwort. Leider gibst den Prefix weiterhin direkt an, nicht als Variable.
Ich habe ein Shellscript x.sh . Ich möchte nun wissen was in x.sh stehen muss,
damit die folgende Session genau mit den dort gezeigten Ausgaben möglich ist:
| export var1="test1"
export var2="test42"
# ... weitere Variablen Definitionen die mit var beginnen.
export varxyz="test"
bash x.sh "var"
|
Ausgabe:
Also alle Variablen Namen die mit dem _beliebigen_ String beginnen, der an x.sh übergeben wird. Die Reihenfolge der Variablen Namen bei der Ausgabe ist unwichtig.
Das Problem ist, dass ich in das Skript nicht einfach echo ${!$1*} Schreiben kann, da sonst ein "bad substitution" Fehler kommt.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12829
|
| $ foo_1=11; foo_2=22; foo_3=33
$ prefix=foo_
$ for v in $(eval "echo \${!$prefix*}"); do echo "var: $v"; echo "val: $(eval echo "\$$v")"; done
var: foo_1
val: 11
var: foo_2
val: 22
var: foo_3
val: 33
|
|
uboat
(Themenstarter)
Anmeldungsdatum: 23. Juni 2009
Beiträge: 178
|
@rklm:
uboat schrieb: Ich könnte mir den String mit dem Prefix aus der Variable zusammenbauen und dann per eval ausführen, hoffe aber, dass es eine andere Lösung gibt.
| x='${!'$prefix'*}'
eval echo $x
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12829
|
uboat schrieb: @rklm:
uboat schrieb: Ich könnte mir den String mit dem Prefix aus der Variable zusammenbauen und dann per eval ausführen, hoffe aber, dass es eine andere Lösung gibt.
Die Hoffnung stirbt zuletzt... 😉
|
track
Anmeldungsdatum: 26. Juni 2008
Beiträge: 7174
Wohnort: Wolfen (S-A)
|
Wenn Du so hartnäckig auf der Form ${!${prefix}*} bestehst, wirst Du um eval wohl nicht herum kommen. Der Meinung ist auch Greg mit seinem Wiki, und das will was heißen ... 😉 Du solltest ernsthaft die Umstellung Deiner Datenhaltung auf Arrays erwägen, da geht das alles. Oder: verrat doch mal, wofür Du das letztlich brauchst. Vielleicht ergibt sich ja aus der Anwendung eine Alternative ? LG, track
|