Wenn ich diese Befehle über ein Skript ausführe:
#my.sh
PWD=bla
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
xxx
bla
es ist in Ordnung.
Aber wenn ich renne:
#my.sh
sed 's/xxx/'$PWD'/'
...
$ ./my.sh
$ sed: -e expression #1, char 8: Unknown option to `s'
Ich habe in Tutorials gelesen, dass Sie zum Ersetzen von Umgebungsvariablen aus der Shell den $varname
Teil stoppen und "aus dem Anführungszeichen" setzen müssen, damit er nicht direkt ersetzt wird. Dies habe ich getan und funktioniert nur, wenn die Variable unmittelbar zuvor definiert wurde.
Wie kann ich sed dazu bringen, eine $var
Umgebungsvariable zu erkennen , wie sie in der Shell definiert ist?
set -x
in der Shell, damit die Shell jeden Befehl unmittelbar vor der Ausführung wiedergibt. Dies kann viel Verwirrung beseitigen. (Außerdem verwende ich oftset -u
, um das De-Referenzieren von nicht gesetzten Variablen zu einem schweren Fehler zu machen. (Sieheset -e
auch.))Antworten:
Ihre beiden Beispiele sehen identisch aus, was die Diagnose von Problemen erschwert. Potenzielle Probleme:
Möglicherweise benötigen Sie doppelte Anführungszeichen wie in
sed 's/xxx/'"$PWD"'/'
$PWD
kann einen Schrägstrich enthalten. In diesem Fall müssen Sie ein Zeichen finden, das nicht in enthalten ist$PWD
, um es als Trennzeichen zu verwenden.Vielleicht, um beide Themen gleichzeitig zu lösen
quelle
Zusätzlich zu Norman Ramseys Antwort möchte ich hinzufügen, dass Sie die gesamte Zeichenfolge in doppelte Anführungszeichen setzen können (wodurch die Anweisung möglicherweise lesbarer und weniger fehleranfällig wird).
Wenn Sie also nach 'foo' suchen und durch den Inhalt von $ BAR ersetzen möchten, können Sie den Befehl sed in doppelte Anführungszeichen setzen.
In der ersten wird $ BAR nicht korrekt erweitert, während in der zweiten $ BAR nicht korrekt erweitert wird.
quelle
"2,$s/^/$foo/"
wenn diese$s
auch als Variable interpretiert werden und dies nicht sollte.Sie können neben "/" auch andere Zeichen als Ersatz verwenden:
quelle
sed
wie Barfing aufgrund der Interpretation/
des Inhalts von $ 2. Dies war genau das, was ich brauchte, um daran vorbei zu kommen. Danke für einen tollen Tipp!Eine weitere einfache Alternative:
Da
$PWD
normalerweise ein Schrägstrich enthalten ist/
, verwenden Sie|
anstelle von/
für die sed-Anweisung:quelle
$PWD
... verwendet?Mit Ihrer Frage bearbeiten sehe ich Ihr Problem. Angenommen, das aktuelle Verzeichnis lautet
/home/yourname
... in diesem Fall der folgende Befehl:wird erweitert auf
das ist nicht gültig. Sie müssen in Ihrem $ PWD
\
vor jedem einen Charakter setzen,/
wenn Sie dies tun möchten.quelle
schlechter Weg: Trennzeichen ändern
vielleicht sind das nicht die endgültige Antwort,
Sie können nicht bekannt , welche Zeichen auftreten in wird
$PWD
,/
:
OR@
.Der gute Weg ist, das Sonderzeichen in zu ersetzen
$PWD
.Guter Weg: Fluchttrennzeichen
Zum Beispiel: Versuchen Sie,
URL
als $ url zu ersetzen (hat:
/
im Inhalt)in string $ tmp
ein. Verwendung
/
als TrennzeichenODER
b. Verwendung
:
als Trennzeichen (besser lesbar als/
)quelle
Tatsächlich ist es am einfachsten (zumindest in gnu sed), ein anderes Trennzeichen für den Befehl sed substitution (s) zu verwenden. Anstatt also s / pattern / '$ mypath' / zu s / pattern // my / path / zu erweitern, was natürlich den Befehl s verwirrt, verwenden Sie s! Pattern! '$ Mypath'! welches zu s! pattern! / my / path! Ich habe den Bang (!) -Zeichen (oder alles, was Sie möchten) verwendet, der den üblichen Schrägstrich als Trennzeichen vermeidet, aber keineswegs Ihre einzige Wahl ist.
quelle
Dabei enthält VAR, durch was Sie das Feld ersetzen möchten
quelle
Umgang mit VARIABLEN innerhalb von sed
quelle
Ich hatte ein ähnliches Problem, ich hatte eine Liste und ich muss ein SQL-Skript basierend auf einer Vorlage erstellen (die
@INPUT@
als zu ersetzendes Element enthalten ist ):quelle