webentwicklung-frage-antwort-db.com.de

Umgebungsvariable Substitution in sed

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 man zum Ersetzen von Umgebungsvariablen aus Shell aufhören und das $varname Teil, so dass es nicht direkt ersetzt wird, was ich getan habe und was nur funktioniert, wenn die Variable unmittelbar zuvor definiert wurde.

Wie kann ich dazu gebracht werden, ein $var als Umgebungsvariable, wie sie in der Shell definiert ist?

160
Roman M

Ihre beiden Beispiele sehen identisch aus, was die Diagnose von Problemen schwierig macht. Potenzielle Probleme:

  1. Möglicherweise benötigen Sie doppelte Anführungszeichen wie in sed 's/xxx/'"$PWD"'/'

  2. $PWD kann einen Schrägstrich enthalten. In diesem Fall müssen Sie ein Zeichen finden nicht in $PWD als Begrenzer verwenden.

Vielleicht, um beide Fragen gleichzeitig zu klären

sed '[email protected]@'"$PWD"'@'
256
Norman Ramsey

Zusätzlich zu der Antwort von Norman Ramsey möchte ich hinzufügen, dass Sie die gesamte Zeichenfolge in Anführungszeichen setzen können (wodurch die Anweisung besser lesbar und weniger fehleranfällig wird).

Wenn Sie also nach 'foo' suchen und es durch den Inhalt von $ BAR ersetzen möchten, können Sie den sed-Befehl in doppelte Anführungszeichen setzen.

sed 's/foo/$BAR/g'
sed "s/foo/$BAR/g"

In der ersten wird $ BAR nicht korrekt erweitert, während in der zweiten $ BAR korrekt erweitert wird.

91
Jeach

Sie können anstelle von "/" auch andere Zeichen verwenden:

sed "s#$1#$2#g" -i FILE
55
Paulo Fidalgo

Eine weitere einfache Alternative:

Schon seit $PWD enthält normalerweise einen Schrägstrich /, verwenden | anstatt / für die sed-Anweisung:

sed -e "s|xxx|$PWD|"
43
Thales Ceolin

Mit deiner Frage bearbeite ich dein Problem. Angenommen, das aktuelle Verzeichnis ist /home/yourname ... in diesem Fall lautet Ihr Befehl unten:

sed 's/xxx/'$PWD'/'

wird erweitert auf

sed `s/xxx//home/yourname//

das ist nicht gültig. Sie müssen vor jedem \ In Ihrem $ PWD ein / - Zeichen einfügen, wenn Sie dies tun möchten.

13
Eddie

schlechter Weg: Trennzeichen ändern

sed 's/xxx/'"$PWD"'/'
sed 's:xxx:'"$PWD"':'
sed '[email protected]@'"$PWD"'@'

vielleicht die nicht die endgültige Antwort,

sie können nicht wissen, welches Zeichen in $PWD, /: OR @ vorkommt.

der gute Weg ist, das Sonderzeichen in $PWD zu ersetzen.

guter Weg: Escape-Begrenzer

beispielsweise:

verwenden Sie / als Trennzeichen

echo ${url//\//\\/}
x.com:80\/aa\/bb\/aa.js

echo ${url//\//\/}
x.com:80/aa/bb/aa.js

echo "${url//\//\/}"
x.com:80\/aa\/bb\/aa.js

echo $tmp | sed "s/URL/${url//\//\\/}/"
<a href="x.com:80/aa/bb/aa.js">URL</a>

echo $tmp | sed "s/URL/${url//\//\/}/"
<a href="x.com:80/aa/bb/aa.js">URL</a>

OR

benutze : als Trennzeichen (lesbarer als /)

echo ${url//:/\:}
x.com:80/aa/bb/aa.js

echo "${url//:/\:}"
x.com\:80/aa/bb/aa.js

echo $tmp | sed "s:URL:${url//:/\:}:g"
<a href="x.com:80/aa/bb/aa.js">x.com:80/aa/bb/aa.js</a>
4
yurenchen
VAR=8675309
echo "abcde:jhdfj$jhbsfiy/.hghi$jh:12345:dgve::" |\
sed 's/:[0-9]*:/:'$VAR':/1' 

wobei VAR enthält, durch was Sie das Feld ersetzen möchten

3
PsychoData

Tatsächlich ist es (zumindest in gnu sed) am einfachsten, ein anderes Trennzeichen für den Befehl sed substitution (s) zu verwenden. Verwenden Sie also s! Pattern! '$ Mypath', anstatt s/pattern/'$ mypath'/zu s/pattern // my/path/zu erweitern, was den Befehl s natürlich verwirrt! was zu s! pattern!/my/path! erweitert wird Ich habe das Zeichen bang (!) Verwendet (oder etwas verwendet, das Sie mögen), wodurch der übliche Schrägstrich, der aber keinesfalls Ihre einzige Wahl ist, als Trennzeichen vermieden wird.

3
adeger

Ich hatte ein ähnliches Problem, ich hatte eine Liste und ich musste ein SQL-Skript auf der Basis einer Vorlage erstellen (die @[email protected] Als zu ersetzendes Element enthielt):

for i in LIST 
do
    awk "sub(/\@INPUT\@/,\"${i}\");" template.sql >> output
done
1
aniskop

mgang mit VARIABLEN innerhalb von sed

[[email protected] ldom]# echo domainname: None > /tmp/1.txt

[[email protected] ldom]# cat /tmp/1.txt

domainname: None

[[email protected] ldom]# echo ${DOMAIN_NAME}

dcsw-79-98vm.us.Oracle.com

[[email protected] ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: ${DOMAIN_NAME}/g'

 --- Below is the result -- very funny.

domainname: ${DOMAIN_NAME}

 --- You need to single quote your variable like this ... 

[[email protected] ldom]# cat /tmp/1.txt | sed -e 's/domainname: None/domainname: '${DOMAIN_NAME}'/g'


--- The right result is below 

domainname: dcsw-79-98vm.us.Oracle.com