在sed表达式中逃脱cat中的新行

时间:2016-08-01 15:23:33

标签: bash shell sed

另一位用户的这个问题被错误地标记为重复,所以我再次发布它,强调问题。

我试图在我的一个xml文件中设置一个私钥,出于安全原因,该私钥保存在外部存储库中。 这是我的bash脚本

    sed -i -e "s/privateKey/`cat privatekey`/g" text.txt

其中privateKey是从存储库下载的密钥,text.txt包含

  <test>
     privateKey
  </test>

运行脚本后,我期待这个:

 <test>
      -----BEGIN RSA PRIVATE KEY-----
      privatekeyblablablablafoooo
      -----END-----------
 </test>

但由于私钥sed的包含让我犯了这个错误

    sed: 1: "s/privateKey/-----BEGIN ...": unescaped newline inside substitute pattern

任何想法如何逃脱cat命令中出现的新行字符?

4 个答案:

答案 0 :(得分:2)

解决方案是简单地使用\\ n预先替换每个新行字符:

cat privatekey | sed ':a;N;$!ba;s/\n/\\n/g'

将此命令放入最终的sed命令:

sed -i -e "s/privateKey/$(cat privatekey | sed ':a;N;$!ba;s/\n/\\n/g')/g" text.txt

唯一剩下的就是正确缩进文件:

sed -i '3,4s/^/\t/' text.txt

注意:显然这不适用于OSX,但它适用于Linux。

答案 1 :(得分:2)

在unix.stackexchange上已经回答了类似的问题 - Substitute pattern within a file with the content of other file

sed -i -e '/privateKey/ {' -e 'r privatekey' -e 'd' -e '}' text.txt

答案 2 :(得分:1)

replace-string-with-contents-of-a-file-using-sed

OSX中的

$ cat t.txt
<test>
privateKey
</test>

$ cat key.file 
-----BEGIN RSA PRIVATE KEY-----
privatekeyblablablablafoooo
-----END-----------

$ f1=$(<key.file)
$ f2=$(<t.txt)

$ echo "${f2//privateKey/$f1}"|tee t.txt
<test>
-----BEGIN RSA PRIVATE KEY-----
privatekeyblablablablafoooo
-----END-----------
</test>
Linux中的

$ sed -e '/privateKey/{r key.file' -e 'd}' t.txt
<test>
-----BEGIN RSA PRIVATE KEY-----
privatekeyblablablablafoooo
-----END-----------
</test>

$ sed -i -e '/privateKey/{r key.file' -e 'd}' t.txt
$ cat t.txt
<test>
-----BEGIN RSA PRIVATE KEY-----
privatekeyblablablablafoooo
-----END-----------
</test>

答案 3 :(得分:0)

最好的答案是根本不使用sed。用于此目的的gawk(GNU awk)函数在BashFAQ #21

中给出
gsub_literal() {
  # STR cannot be empty
  [[ $1 ]] || return

  # string manip needed to escape '\'s, so awk doesn't expand '\n' and such
  gawk -v str="${1//\\/\\\\}" -v rep="${2//\\/\\\\}" '
    # get the length of the search string
    BEGIN {
      len = length(str);
    }

    {
      # empty the output string
      out = "";

      # continue looping while the search string is in the line
      while (i = index($0, str)) {
        # append everything up to the search string, and the replacement string
        out = out substr($0, 1, i-1) rep;

        # remove everything up to and including the first instance of the
        # search string from the line
        $0 = substr($0, i + len);
      }

      # append whatever is left
      out = out $0;

      print out;
    }
  '
}

...可以用作:

gsub_literal privateKey "$(<privatekey)"

请注意需要GNU awk - MacOS附带的BSD awk将失败并显示awk: newline in string