2016-08-01 7 views
1

Diese Frage von einem anderen Benutzer wurde fälschlicherweise als doppelt markiert, so dass ich es erneut poste, das Problem hervorhebend.Escape neue Zeilen von Katze in sed Ausdruck

Ich versuche in einer meiner XML-Dateien einen privaten Schlüssel zu setzen, der aus Sicherheitsgründen in einem externen Repository gespeichert wird. Das ist mein Bash-Skript

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

Wo privateKey meinen Schlüssel aus einem Repository und text.txt heruntergeladen wird, enthält

<test> 
    privateKey 
    </test> 

Nachdem das Skript ausführen ich dieses erwartete:

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

Aber wegen der Inhalte des privaten Schlüssels sed bekommt mir dieser Fehler

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

Eine Idee, wie kann ich die neuen Zeilen Zeichen entkommen, die aus dem Cat-Befehl kommen?

+0

Haben Sie darüber nachgedacht, ein anderes Werkzeug als 'sed' zu verwenden? –

+1

...Übrigens, wenn Sie denken, dass eine Frage erneut geöffnet werden soll, können Sie sie einfach bearbeiten - damit wird sie in die Warteschlange gestellt, damit sie wieder geöffnet werden kann. Auf diese Weise erhalten wir keine Wissensbasis mit verschiedenen Varianten derselben Dinge, die ursprüngliche Person wird benachrichtigt, wenn es eine Antwort gibt (und Kredit/Repo für ihre Frage), & c. –

Antwort

1

Die Lösung ist einfach mit jeder neuen Zeile-Zeichen ersetzen \\ n vorher:

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

einfach diesen Befehl setzen in Ihrem letzten sed Befehl:

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

Das einzige, was links ist Um die Datei richtig einzurücken:

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

Hinweis: Offenbar funktioniert dies nicht auf OSX, aber es funktioniert mit Linux.

+0

es gibt mir genau den gleichen Fehler :(Ich werde überprüfen, ob ich etwas anderes vermisse – paul

+0

Benutzt du GNU sed? Ich habe es gerade noch einmal probiert, es funktioniert perfekt für mich. –

+0

Ich benutze osx aber benutze -e sollte funktionieren, aber nichts habe ich immer noch den gleichen Fehler mit sed -i -e "s/privateKey/$ (cat-privatekey | sed ': a; N; $! ba; s/\ n/\\ n/g')/g "text.txt habe ich schließlich mit sed -i -e '2r privatekey.txt' text.txt gelöst, aber ich möchte überhaupt nicht angeben, in welcher Zeile ich wollte – paul

2

Ein ähnliches Problem hat auf unix.stackexchange beantwortet - Substitute pattern within a file with the content of other file:

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

es ist sed Rückkehr: 1: "/privateKey/{": unerwartetes EO F (pending} s) – paul

+0

können Sie versuchen, die zweite Option, die in diesem Thread, mit dem ich verknüpft habe, erklärt? kenne die Unterschiede zwischen GNU sed und der in OSX nicht – Sundeep

1

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

in 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> 

in 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> 
+0

es gibt sed zurück: 1: "/ privateKey/{r privatek ...": unerwartete EOF (ausstehende} s) Ich benutze OSX, sind verwendest du Linux? – paul

+0

'sed -i -e' ist ein sicheres Zeichen einer Antwort, die für GNU sed geschrieben wurde (das in MacOS angegebene BSD sed erlaubt' -i' nicht ohne ein Argument, das ein Suffix für Backup-Dateien angibt). –

+0

ja 'sed' ist für Linux und' echo + variables' ist für OSX - siehe aktualisierte Antwort –

0

Die beste Antwort ist, sed dafür überhaupt nicht zu verwenden. Ein gawk (GNU awk) Funktion für den Zweck ist in BashFAQ #21 gegeben:

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; 
    } 
    ' 
} 

..., die als verwendet werden können:

gsub_literal privateKey "$(<privatekey)" 

Notiere die Notwendigkeit für GNU awk - der BSD awk ausgeliefert mit MacOS wird mit awk: newline in string fehlschlagen.