sed 中单引号的反斜杠转义会产生错误

sed 中单引号的反斜杠转义会产生错误

目的是HEAD在旧版 HTML 网站中的 Google 标签代码之后立即插入。

#!/bin/bash

find . -type f -iname "*.php" -or -iname "*.htm" -or -iname "*.html" | while read i; do
    echo "Processing: $i"
    sed -i 's*<HEAD>*&\
<!-- Global site tag (gtag.js) - Google Analytics -->\
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1234567-2"></script>\
<script>\
  window.dataLayer = window.dataLayer || [];\
  function gtag(){dataLayer.push(arguments);}\
  gtag('js', new Date());\
\
  gtag('config', 'UA-1234567-2');\
</script>*' "$i"

done

以上将 Google 标签代码放在应有的位置,但没有单引号:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-1234567-2"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag(js, new Date());

  gtag(config, UA-1234567-2);

处理后,单引号丢失:

# diff actual_google_tag_code processed
6c6
<   gtag('js', new Date());
---
>   gtag(js, new Date());
8,9c8
<   gtag('config', 'UA-1234567-2');
< </script>
---
>   gtag(config, UA-1234567-2);

如果我将 替换'\',我会收到一条错误消息:

line 13: syntax error near unexpected token `('
line 13: `  gtag(\'js\', new Date());\'

由于我使用它\来继续每一行,所以我不确定使用反斜杠来转义单引号是否有效,但我想我会尝试一下。

如何在 Google Tag 代码中保留这些单引号?

答案1

man 1 bash

将字符括在单引号中可保留引号内每个字符的字面值。单引号之间不能出现单引号,即使前面有反斜杠。

解决方案:将单引号放在双引号内:

  gtag('"'js'"', new Date());\
#      ^        - single quote was opened earlier, this character closes it
#       ^^^^^^  - these are double quotes with content, single quotes are part of the content
#             ^ - this single quote will be closed later
# Do not paste these comments into your script.

在你需要的地方重复这个技巧,它将会像:

  gtag('"'config', 'UA-1234567-2'"');\

(请记住,这一行是上一行的延续,其中单引号已经打开;最后它将其保持打开状态,以便在下一行关闭)。

一般来说,可以只放在'双引号中,其他所有内容都放在单引号中,例如:

echo '$A'"'"'$B'"'"'$C'
#     ^^     ^^     ^^ - in single quotes, so no variable expansion here
#         ^      ^     - in double quotes, so ' is possible

結果是$A'$B'$C

相关内容