Kann ich Variablen innerhalb der {}
Erweiterung verwenden, ohne sie anzusprechen eval
? Wenn das so ist, wie?
Das funktioniert nicht:
$ touch 1.foo 1.bar
$ ls 1.{foo,bar}
1.bar 1.foo
$ extensions=foo,bar
$ ls 1.{$extensions}
ls: cannot access 1.{foo,bar}: No such file or directory
Es funktioniert mit eval
:
$ eval ls 1.{$extensions}
1.bar 1.foo
Antworten:
Die Erweiterung der Zahnspange erfolgt sehr früh während der Erweiterung (tatsächlich als erstes), bevor die Variable erweitert wird. Um eine Klammererweiterung für das Ergebnis einer variablen Erweiterung durchzuführen, müssen Sie verwenden
eval
.Sie können ohne die gleiche Wirkung erzielen ,
eval
wenn Sie machenextensions
ein Wildcard - Muster statt einer Klammer Muster. Stellen Sie dieextglob
Option zum Aktivieren von ksh-ähnlichen Mustern ein .quelle
Hier ist eine Möglichkeit, Variablen in geschweiften Klammern ohne Auswertung zu erweitern :
Wir haben jetzt eine schöne Reihe von Zahlen:
Getestet in Bash 4.3.11, sollte aber in allen modernen Versionen funktionieren.
quelle
read line; declare -a "l=($line)"; echo ${l[@]}
- Ich habe diese platziert, damit ein Benutzer erweiterte Klammern eingeben und das Ergebnis anzeigen kann (in einer Art Bash-Tutorial).eval
das nicht weniger gefährlich alseval
. Mitend='$(reboot)'
,reboot
ist genau das gleiche laufen.Eine andere Technik, die Sie in Bash und einigen anderen Shells verwenden können, ist die Verwendung eines Arrays:
Dies ist die (Mustersubstitutions-) Form der Parametererweiterung. (Leider ist dies auch nicht POSIX-kompatibel.) Das gibt an, dass die Substitution auf jedes Element des Arrays angewendet werden soll und dass die Trennung zwischen den Elementen beibehalten werden soll. in einem Muster wirkt die Zeichenfolge wie ein regulärer Ausdruck (dh die meisten Substitutionen); Dies bedeutet, dass die Ersetzung nur am Anfang der Parameterwerte erfolgen sollte. Damit
${parameter/pattern/string}
[@]
#
^
s/old/new/
ist äquivalent zu
(da dieses Array zwei Elemente hat, die als 0 und 1 indiziert sind) und dies erweitert sich auf
Zitieren
Die Anführungszeichen sind wichtig, wenn für die „Erweiterungen“ Anführungszeichen erforderlich sind, dh wenn sie (möglicherweise jemals) Leerzeichen oder Zeichen zur Erweiterung des Pfadnamens (Glob / Wildcard) enthalten. Zum Beispiel wenn
dann
(ohne Anführungszeichen) würde auf erweitern
(in denen
1.foo
undbar
sind separate Argumente), und dies wiederum erweitert sich auf(weil
1.*r
es sich um einen nicht zitierten Platzhalter handelt). Weitere Informationen zur Wichtigkeit des Zitierens finden Sie unter Auswirkungen auf die Sicherheit, wenn Sie vergessen, eine Variable in Bash / POSIX-Shells zu zitieren .Sie können das Ende einer Zeichenfolge auch mit
%
dem folgenden Muster abgleichen :erweitert sich auf
Aber Vorsicht: Funktioniert
%
nicht wie$
in regulären Ausdrücken. Sie müssen es am Anfang des Musters einfügen, um die Übereinstimmung am Ende des Parameterwerts einzuschränken. Zum Beispiel, wenn Sie habenund Sie bekommen
cat.o
unddog.o
, nicht tun"${fnames[@]/.c%/.o}"
- es wird nicht funktionieren. TunAber tun Sie es auch nicht
"${fnames[@]/.c/.o}"
(lassen Sie das%
Ganze weg) - wenn einer der „fnames“ istdog.catcher.c
, wird er in konvertiert (da der erste durch ersetzt wird ).dog.oatcher.c
.c
.o
Leider gibt es keine einfache Möglichkeit, ein Präfix und ein Suffix hinzuzufügen, wie Sie es könnten
Weitere Informationen zu Variablen, Arrays und den Transformationen, die Sie auf sie anwenden können, finden Sie in der Bash-Dokumentation.
quelle