Ein Backslash-Escape für ein einfaches Anführungszeichen in sed führt zu einem Fehler

928
Edward_178118

Es ist beabsichtigt, direkt nach dem HEADGoogle-Tag-Code in eine ältere HTML-Website einzufügen .

#!/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 

Mit dem obigen Code wird der Google-Tag-Code an den richtigen Ort gesetzt, jedoch ohne die Anführungszeichen:

<!-- 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); 

Die einfachen Anführungszeichen fehlen, nachdem sie verarbeitet wurden:

# 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); 

Wenn ich das 'durch a ersetze \', erhalte ich eine Fehlermeldung:

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

Da ich \jede Zeile fortsetzen möchte, war ich mir nicht sicher, ob der Backslash, der dem einfachen Anführungszeichen entgeht, funktionieren würde, aber ich dachte, ich würde es versuchen.

Wie kann ich diese einfachen Anführungszeichen im Google-Tag-Code beibehalten?

0
https://www.shellcheck.net/ zeigt, dass Ihr ursprünglicher Code furchtbar kaputt ist (die Antwort ist mir jedoch nicht bekannt). Viele Warnungen "Dieser umgekehrte Schrägstrich + Zeilenvorschub ist wörtlich. Unterbrechen Sie die Anführungszeichen, wenn Sie nur die Zeile brechen wollen." denn alles befindet sich in einer einzigen Anführungszeichenfolge, beginnend bei der `sed`-Zeile. DavidPostill vor 6 Jahren 0
Ich weiß nicht, ob dies portabel ist, aber in GNUsed könnte es mit hexadezimalem Escape `sed 's / f / \ x27 /' << kommen Paulo vor 6 Jahren 0

1 Antwort auf die Frage

1
Kamil Maciorowski

Von man 1 bash:

Wenn Sie Zeichen in einfache Anführungszeichen setzen, wird der Wert jedes Zeichens in den Anführungszeichen beibehalten. Ein einfaches Anführungszeichen darf nicht zwischen einfachen Anführungszeichen stehen, auch wenn ein Backslash vorangestellt ist.

Lösung: Setzen Sie einfache Anführungszeichen in doppelte Anführungszeichen:

 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. 

Wiederholen Sie diesen Trick, wo immer Sie möchten. Es wird wie folgt aussehen:

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

(Denken Sie daran, dass diese Zeile mit dem vorherigen fortgesetzt wird, wo ein einzelnes Zitat bereits geöffnet ist; am Ende wird es geöffnet, um in der nächsten Zeile geschlossen zu werden).

Im Allgemeinen ist es möglich, nur 'in doppelte Anführungszeichen zu setzen, alles andere in einfache Anführungszeichen, z.

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

Das Ergebnis ist $A'$B'$C.

Ich habe versucht, die Anführungszeichen in doppelte Anführungszeichen zu setzen, was jedoch dazu führte, dass ein doppeltes Anführungszeichen anstelle eines einzelnen Anführungszeichens verwendet wurde. Fehlt mir etwas? Edward_178118 vor 6 Jahren 0
gtag ('' 'js' '', neues Datum ()); \ funktioniert, und gtag ('' 'config', 'UA-1234567-2' ''); \ Ich habe es nur schwer zu verstehen warum das funktioniert :-) Edward_178118 vor 6 Jahren 0
@ Edward_178118 Ersetzen Sie einfach Ihre beiden Zeilen durch meine entsprechenden. Der Trick besteht nicht nur darin, diese einfachen Anführungszeichen doppelt zu zitieren. Sie müssen ein altes einfaches Anführungszeichen schließen und kurz danach erneut öffnen. Ungültige '' foo'bar '' wird zum gültigen '' foo '"" "" bar "". Kamil Maciorowski vor 6 Jahren 0
Sie sagten: "Das einzelne Zitat wurde früher geöffnet". Wo ist es früher geöffnet? Das erste einfache Anführungszeichen ist in gtag ('? Edward_178118 vor 6 Jahren 0
Das erste einzelne Zitat ist das? Edward_178118 vor 6 Jahren 0
@ Edward_178118 In der modifizierten Version hier: `sed -i 's ** & \` - die Zeile geht weiter. Kamil Maciorowski vor 6 Jahren 0