例如,我有一个文本文件,input.txt
其中包含这句话:
This is my base64 string: ${BASE64}
我有这个变量:
myvar="SGVsbG8gV29ybGQuIERvIHlvdSBsaWtlIG15IGJhc2U2NCBzdHJpbmc/IFRoYXQgaXMgdmVyeSBuaWNlIQ=="
预期输出:
This is my base64 string: SGVsbG8gV29ybGQuIERvIHlvdSBsaWtlIG15IGJhc2U2NCBzdHJpbmc/IFRoYXQgaXMgdmVyeSBuaWNlIQ==
我认为这个命令应该可以完成工作,但它给出了一个错误。
$ sed -i -e "s/\${BASE64}/${myvar}/g" text.txt
sed: -e expression #1, char 70: unknown option to `s'
我尝试了很多选择,并在互联网上搜索了几个小时,但我无法准确地弄清楚。我认为这与\
首先我想知道我做错了什么?其次我想知道如何正确地做到这一点。我也喜欢一个正确的 awk 示例。
答案1
主要问题是你说的:我认为这与/有关。
当您使用 with/
作为分隔符时,您必须小心使用的字符串。
因此,您应该在sed
命令中使用另一个分隔符:
sed -i -e "s@\${BASE64}@${myvar}@g" text.txt
使用 awk
myvar="SGVsbG8gV29ybGQuIERvIHlvdSBsaWtlIG15IGJhc2U2NCBzdHJpbmc/IFRoYXQgaXMgdmVyeSBuaWNlIQ=="
awk -i inplace -v var='\\$\\{BASE64\\}' -v base="$myvar" '{sub(var,base);}1'
替换变量的另一种方法是使用envsubst
.如果您的文件包含,${BASE64}
您可以创建一个具有相同名称的变量并在文件中替换它。但你必须导出该变量(就一次)在运行之前envsubst
:
BASE64="SGVsbG8gV29ybGQuIERvIHlvdSBsaWtlIG15IGJhc2U2NCBzdHJpbmc/IFRoYXQgaXMgdmVyeSBuaWNlIQ=="
export BASE64
#Not recommended:
envsubst < text.txt | tee text.txt
#Or
envsubst < text.txt > newtext.txt
mv newtext.txt text.txt
答案2
使用 Perl 可能更容易做到这一点,因为它可以从环境变量中读取替换字符串,因此您不需要将其嵌入到代码中:
repl=$myvar perl -i -pe 's/\${BASE64}/$ENV{repl}/' input.txt
(这应该是安全的,不会对任何特殊序列进行评估)
答案3
使用乐(以前称为 Perl_6)
~$ env repl="SGVsbG8g_ETCETERA_==" raku -pe 's/\$\{BASE64\}/{ %*ENV<repl> }/' file.txt
#OR
~$ env repl="SGVsbG8g_ETCETERA_==" raku -pe 's/\$\{BASE64\}/%*ENV<repl>/' file.txt
输入示例:
This is my base64 string: ${BASE64}
示例输出(使用截断替换、全长替换也同样有效):
This is my base64 string: SGVsbG8g_ETCETERA_==
这个答案与 @ilkkachu 的 Perl 答案非常相似(谢谢!)。该env
变量的拼写略有不同:%*ENV
是包含 Raku 的(动态)操作系统环境变量的哈希,并且<repl>
是您无需引用即可调用单个键的方式。请注意,两个 Raku 答案仅在{ … }
插入大括号方面有所不同。请参阅下面的 NNTP 线程以获取源代码(技巧#8)。
https://docs.raku.org/language/variables#index-entry-$PERCENT_SIGN*ENV
https://www.nntp.perl.org/group/perl.perl6.users/2020/07/msg9004.html
https://raku.org