Обратная косая черта для одинарной кавычки в sed выдает ошибку

892
Edward_178118

Намерение состоит в том, чтобы вставить сразу после HEADкода тега Google на устаревшем веб-сайте HTML.

#!/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()\ 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() 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?

0
https://www.shellcheck.net/ показывает, что ваш оригинальный код ужасно сломан (хотя я не знаю ответа). Много предупреждений «Этот обратный слеш + перевод строки является буквальным. Вырвитесь за пределы одинарных кавычек, если вы просто хотите разорвать строку». потому что все находится внутри одной строки в кавычках, начиная с строки `sed`. DavidPostill 6 лет назад 0
Я не знаю, переносимо ли это, но в GNUsed может быть с шестнадцатеричным escape `sed 's / f / \ x27 /' << Paulo 6 лет назад 0

1 ответ на вопрос

1
Kamil Maciorowski

От 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.

Я попытался поместить двойные кавычки вокруг одинарных кавычек, но в результате получилась двойная кавычка вместо одной. Я что-то пропустил? Edward_178118 6 лет назад 0
gtag ('"' js '"', new Date ()); \ работает и так же работает gtag ('"' config ',' UA-1234567-2 '"'); \ Мне просто трудно понять почему это работает. :-) Edward_178118 6 лет назад 0
@ Edward_178118 Просто замени свои две строки на мои соответствующие. Хитрость заключается не просто в двойных кавычках этих одинарных кавычек; Вы должны закрыть старую одинарную кавычку непосредственно перед тем, как открыть ее сразу после. Неверный `'foo'bar'` становится действительным`' foo '"'" 'bar'`. Kamil Maciorowski 6 лет назад 0
Вы сказали: «Единая кавычка была открыта раньше». Где он открыт раньше? Первая одиночная кавычка в gtag ('? Edward_178118 6 лет назад 0
Первая одиночная кавычка - это? Edward_178118 6 лет назад 0
@ Edward_178118 В модифицированной версии, здесь: `sed -i 's ** & \` - строка продолжается. Kamil Maciorowski 6 лет назад 0