Более длинная, но более надежная версия принятого ответа:
perl -pe 's;(\\*)(\$([a-zA-Z_][a-zA-Z_0-9]*)|\$\{([a-zA-Z_][a-zA-Z_0-9]*)\})?;substr($1,0,int(length($1)/2)).($2&&length($1)%2?$2:$ENV{$3||$4});eg' template.txt
Это расширяет все экземпляры $VAR
или ${VAR}
до их значений среды (или, если они не определены, пустой строки).
Он корректно избегает обратной косой черты и принимает $ с обратной косой чертой, чтобы запретить замену (в отличие от envsubst, который, оказывается, этого не делает ).
Итак, если ваша среда:
FOO=bar
BAZ=kenny
TARGET=backslashes
NOPE=engi
и ваш шаблон:
Two ${TARGET} walk into a \\$FOO. \\\\
\\\$FOO says, "Delete C:\\Windows\\System32, it's a virus."
$BAZ replies, "\${NOPE}s."
результат будет:
Two backslashes walk into a \bar. \\
\$FOO says, "Delete C:\Windows\System32, it's a virus."
kenny replies, "${NOPE}s."
Если вы хотите избежать обратной косой черты до $ (вы можете написать «C: \ Windows \ System32» в шаблоне без изменений), используйте эту слегка измененную версию:
perl -pe 's;(\\*)(\$([a-zA-Z_][a-zA-Z_0-9]*)|\$\{([a-zA-Z_][a-zA-Z_0-9]*)\});substr($1,0,int(length($1)/2)).(length($1)%2?$2:$ENV{$3||$4});eg' template.txt