Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[bash] Ersetzen mit $x

4 views
Skip to first unread message

Andreas Kohlbach

unread,
Jul 2, 2023, 11:48:30 PM7/2/23
to
Wenn ich

for x in `seq 1000`; do echo laufende_nummer_$x ; done

eingebe, bekomme ich wie gewünscht

...
laufende_nummer_997
laufende_nummer_998
laufende_nummer_999
laufende_nummer_1000

Bei

for x in `seq 1000`; do echo laufende_$x_nummer ; done

aber

...
laufende_
laufende_
laufende_
laufende_

Erst bei ('$x' direkt in Quotes)

for x in `seq 1000`; do echo laufende_"$x"_nummer ; done

kommt auch da das gewünschte Ergebnis.

...
laufende_997_nummer
laufende_998_nummer
laufende_999_nummer
laufende_1000_nummer

Warum wird das nicht gequotete '$x' ersetzt, wenn es am Ende, aber
nicht, wenn es zwischendurch steht?
--
Andreas

Stefan Kanthak

unread,
Jul 3, 2023, 12:36:39 AM7/3/23
to
"Andreas Kohlbach" <a...@spamfence.net> schrieb:

[ echo laufende_nummer_$x vs. echo laufende_$x_nummer ]

> Warum wird das nicht gequotete '$x' ersetzt, wenn es am Ende, aber
> nicht, wenn es zwischendurch steht?

Anfaengerfehler und GAAANZ schlechter Stil!

Sobald Du den Unterschied zwischen
echo laufende_${x}_nummer
und
echo laufende_${x_nummer}
erkannt hast wirst Du (Shell- und Umgebungs-) Variable nie mehr ohne
die geschweiften Klammern schreiben wollen.

Stefan
--
<https://www.duden.de/rechtschreibung/Kanthaken>

Jens Schüßler

unread,
Jul 3, 2023, 6:00:05 AM7/3/23
to
* Andreas Kohlbach <a...@spamfence.net> [03-07-23 03:48]:
> Wenn ich
>
> for x in `seq 1000`; do echo laufende_nummer_$x ; done
>
> eingebe, bekomme ich wie gewünscht
>
> ...
> laufende_nummer_997
>
> for x in `seq 1000`; do echo laufende_$x_nummer ; done
>
> aber
>
> ...
> laufende_
> laufende_
> laufende_
> laufende_
>
> Warum wird das nicht gequotete '$x' ersetzt, wenn es am Ende, aber
> nicht, wenn es zwischendurch steht?

Weil die bash keine Variable "$x_nummer" kennt. Das war jetzt einfach.

Aber wie ich dich kenne akzeptierst du das nicht, stampfst mit dem Fuß
auf und es geht ein ellenlanger Thread los.

Stefan Kanthak

unread,
Jul 4, 2023, 3:58:10 AM7/4/23
to
"Andreas Kohlbach" <a...@spamfence.net> schrieb:

> On Mon, 3 Jul 2023 06:34:12 +0200, Stefan Kanthak wrote:
>>
>> "Andreas Kohlbach" <a...@spamfence.net> schrieb:
>>
>> [ echo laufende_nummer_$x vs. echo laufende_$x_nummer ]
>>
>>> Warum wird das nicht gequotete '$x' ersetzt, wenn es am Ende, aber
>>> nicht, wenn es zwischendurch steht?
>>
>> Anfaengerfehler und GAAANZ schlechter Stil!
>>
>> Sobald Du den Unterschied zwischen
>> echo laufende_${x}_nummer
>> und
>> echo laufende_${x_nummer}
>> erkannt hast wirst Du (Shell- und Umgebungs-) Variable nie mehr ohne
>> die geschweiften Klammern schreiben wollen.
>
> Danke.
>
> Ich hatte das (ohne Klammern0 irgendwann mal als Beispiel gefunden,

Gute Beispiele zeigen die DEFENSIVE (kanonische) Schreibweise, auch wenn
diese redundant sein sollte.

> dass ich das mit zog, bis das Problem neulich kam, weil die variable
> nicht am Ende steht.
>
> Oder wo noch als am Ende?

Ersetze 'am (Zeilen-)Ende' durch 'vor Trennzeichen'.

> Denn qwerty$x@ytrewq funktioniert auch ohne Klammern

Weil @ zufaelligerweise kein Zeichen aus der Menge der fuer Variablennamen
zulaessigen Zeichen (Gross/kleinbuchstaben, Ziffern, Unterstrich) ist.

JFTR: ungueltige Namen wie @ oder _ erfahren als ${@} und ${_} aber eine
besondere und sogar kontextabhaengige Aufloesung.

Da Du Dich hier auf bash beschraenkt hast: siehe
<https://www.gnu.org/software/bash/manual/html_node/Definitions.html#index-name>
und
<https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html>
| The basic form of parameter expansion is ${parameter}.

Die entsprechenden Definitionen in SUS oder POSIX findest Du selbst?

> (wenn eben kein guter Stil).

Stefan
--
<https://www.duden.de/rechtschreibung/Kanthaken>

Helmut Waitzmann

unread,
Jul 4, 2023, 5:27:40 AM7/4/23
to
Andreas Kohlbach <a...@spamfence.net>:
Wenn der Parser im Shell, der die Kommandozeile zerlegt, erkennt,
dass das dem „$“ folgende Zeichen der Beginn eines
Variablennamens sein könnte, versucht er, auch die ihm folgenden
Zeichen dem Variablennamen zuzuschlagen; und er fährt damit so
lange fort, bis er auf ein Zeichen stößt, das nicht Teil eines
Variablennamens sein kann.


=> Da die Zeichen „_“, „n“, „u“, „m“, „e“ und „r“ in
Variablennamen vorkommen können, vereinnahmt sie der Parser
dafür.  Ob es dabei eine Variable mit dem so entstandenen
Namen tatsächlich gibt, juckt den Parser nicht.


Im Gegensatz dazu können die Zeichen „"“ und „}“ kein Teil eines
Variablennamens sein.  Daher zeigen sie dem Parser das Ende des
Variablennamens an.


Die eine Lösung, Variablennamen stets in Anführungszeichen zu
setzen, hast du bereits selbst erkannt, die andere, sie stets
mittels der Variablenexpansionssyntax „${…}“ zu verwenden, hat
Stefan in seiner unnachahmlichen Art aufgezeigt.  (Auch die
Kombination mit Schweifklammern und Anführungszeichen „"${…}"“
ist möglich.)


Weil es hier gerade um Parameter‐Expansionen („parameter“ ist im
POSIX‐Standard der Oberbegriff, der Variable mit Namen, spezielle
Parameter wie beispielsweise „$?“, „$!“, „$#“ oder „$-“, und die
positional parameters (s. u.) umfasst) geht:


Ein wenig anders verhält es sich bei den positional parameters,
die „Namen“ haben, die nur aus Ziffern bestehen, wie „$0“,
„$1“ und so fort.  Da erkennt der Parser ohne die
Schweifklammerschreibweise „${…}“ nur einstellige Zahlen, also
von 0 bis 9.  Ab dem zehnten Parameter sind die Schweifklammern
(also Stefans Rat) Pflicht.


Probiere die folgende Kommandozeile aus:


(
set -- eins zwei drei vier fuenf \
sechs sieben acht neun zehn elf zwoelf &&
printf '%s\n' 'Ohne Schweifklammern:' &&
printf '%s\n' "$1" "$2" "$3" "$4" "$5" \
"$6" "$7" "$8" "$9" "$10" "$11" "$12" &&
printf '%s\n' 'Mit Schweifklammern:' &&
printf '%s\n' "${1}" "${2}" "${3}" "${4}" "${5}" \
"${6}" "${7}" "${8}" "${9}" "${10}" "${11}" "${12}"
)

Beobachte, was aus „"$10"“, „"$11"“ und „"$12"“ für eine Ausgabe
entsteht.

0 new messages