如何在sed命令中使用变量

时间:2015-04-20 13:51:04

标签: bash shell sed

我有一个名为" text_file1.txt"并且文件中的内容是 " subject = / C = US / O = AAA / OU = QA / OU = 12345 / OU = TESTAPP /"

现在我要实现的内容如下: " subject = / C = US / O = AAA / $$$ QA / ### 12345 / @@@ TESTAPP /"

当我执行下面的代码时:

#! /bin/ksh
OU1="QA"
OU2=12345
OU3="TESTAPP"
`sed -i "s/OU=$OU1/$$$\${OU1}/g" text_file1.txt`
`sed -i "s/OU=$OU2/###\${OU2}/g" text_file1.txt`
`sed -i "s/OU=$OU3/@@@\${OU3}/g" text_file1.txt`
content=`cat text_file1.txt`
echo "content:$content"

我得到这样的输出:

content:subject= /C=US/O=Wells Fargo/2865528655{OU1}/###12345/@@@TESTAPP/CN=03032015_CUST_2131_Unix_CLBLABB34C02.wellsfargo.com

只有这个命令" sed -i "s/OU=$OU1/$$$\${OU1}/g" text_file1.txt"没有按预期工作。任何人都可以就此提出一些建议吗?

提前致谢。

3 个答案:

答案 0 :(得分:2)

有两件事情可以解决这个问题:

  1. 如果你想要一个文字$
  2. ,你必须在双引号shell字符串中转义\$(即使用$
  3. \$内部反引号之前不会保留其字面含义(也就是说,内部反引号,\$变为$)。< / LI>

    写作时

    `sed -i "s/OU=$OU1/$$$\${OU1}/g" text_file1.txt`
    

    因为命令在反引号中,所以使用命令

    生成子shell
    sed -i "s/OU=$OU1/$$$${OU1}/g" text_file1.txt
    

    由于$$$$位于双引号字符串中,因此会发生变量扩展,并将其扩展为两次出现$$(进行扩展的shell的进程ID) )。这意味着代码sed最终会看到

    s/OU=QA/1234512345{OU1}/g
    

    ...如果生成的子shell的进程ID是12345

    在这种特殊情况下,你不需要命令替换(反引号),所以你可以写

    sed -i "s/OU=$OU1/\$\$\$${OU1}/g" text_file1.txt
    

    但是,在sed代码中使用shell变量始终是个问题。如果你愿意的话,考虑如果OU1具有值/; e rm -Rf * #会发生什么(提示:GNU sed有一个运行shell命令的e指令)。出于这个原因,我总是希望awk进行涉及shell变量的替换:

    cp text_file1.txt text_file1.txt~
    awk -v OU1="$OU1" '{ gsub("OU=" OU1, "$$$" OU1) } 1' text_file1.txt~ > text_file1.txt
    

    这可以通过不将OU1视为代码来避免代码注入问题。

    如果你有GNU awk 4.1或更高版本,

    awk -v OU1="$OU1" -i inplace  '{ gsub("OU=" OU1, "$$$" OU1) } 1' text_file1.txt
    

    可以在没有(可见)临时文件的情况下完成所有操作。

答案 1 :(得分:0)

$放在双引号内时一定要小心。

sed -i "s/OU=$OU1/"'$$$'"${OU1}/g" text_file1.txt

示例:

$ OU1="QA"
$ echo 'OU=QA' | sed "s/OU=$OU1/"'$$$'"${OU1}/g"
$$$QA

答案 2 :(得分:0)

这有助于开始吗?

echo ''
OU1="QA"
echo "subject= /C=US/O=AAA/OU=${OU1}/OU=12345/OU=TESTAPP/" \
| sed -e "s|/OU=${OU1}/|/OU=\$\$\$${OU1}/|g"

结果是:

subject = / C = US / O = AAA / OU = $$$ QA / OU = 12345 / OU = TESTAPP /

(你混淆了$ sign的使用。)