Ich versuche diesen Befehl auszuführen
sed -i -e "s/BASE_64/$BASE_64/" FILE_NAME
wobei es $BASE_64
sich um eine Base64-Darstellung eines Dateiinhalts handelt.
sed
gibt mir einen Fehler, da die Zeichenfolge zu lang ist.
Argumentliste zu lang
Wie kann dieser Fehler vermieden werden?
Antwort1
sed
Sie könnten immer Folgendes tun (da Sie bereits GNU ( ) verwenden -i
):
sed -i -f - FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF
-f -
weist an sed
, das Sed-Skript von stdin zu lesen.
Wenn Sie unter Linux (und nur Linux) mit einer Shell wie und einer Version bis zu 5.0, zsh
die Here-Dokumente mit temporären Dateien implementiert (im Gegensatz zu Pipes wie oder (oder 5.1+) für relativ kleine Heredocs und immer noch mit GNU ) , ksh
dasselbe Skript für mehrere Dateien wiederverwenden möchten , können Sie Folgendes tun:bash
dash
yash
bash
sed
find . -name '*.conf' -exec sed -i -f /dev/stdin {} + << EOF
s/BASE_64/$BASE_64/g
EOF
Unter Linux (und nur Linux und Cygwin) /dev/stdin
bedeutet dies nichtstdinauf die gleiche Weise -
. Stattdessen handelt es sich um einen symbolischen Link zu der Datei, die auf stdin geöffnet wird, sodass sed
die Datei bei jedem Öffnen von Anfang an neu geöffnet wird. Der obige Befehl würde auf anderen Systemen (die über verfügen /dev/stdin
) oder mit Shells, die Here-Dokumente mit Pipes implementieren, einwandfrei funktionieren, aber nur, wenn nur wenige conf
Dateien vorhanden sind, die sed
nur einmal aufgerufen werden. Beim zweiten Aufruf auf Nicht-Linux/Cygwin-Systemen, wie mit -f -
, /dev/stdin
würde es leer erscheinen, da es bereits beim ersten Aufruf gelesen wurde.
busybox
sed
unterstützt ebenfalls -i
auf die gleiche Weise wie GNU sed
, unterstützt jedoch nicht -f -
. Sie sollten -f /dev/stdin
es also auf jeden Fall verwenden. sed
Verwenden Sie unter FreeBSD:
sed -i '' -f /dev/stdin FILE_NAME << EOF
s/BASE_64/$BASE_64/g
EOF
Antwort2
Speichern Sie zunächst die Base64-codierten Daten in einer Datei mit dem Namen beispielsweise base64.txt
.
Zum Beispiel:
base64 < originalfile > base64.txt
Dann:
printf '%s\n' '/BASE64/r base64.txt' 1 '/BASE64/d' w | ed FILENAME
Dies verwendet ed
zum Suchen in FILENAME
nach einer Zeile, die die Zeichenfolge enthält BASE64
, zum Einfügen des Inhalts von base64.txt
nach dieser Zeile, zum Zurückgehen zur ersten Zeile, zum BASE64
erneuten Suchen nach der Zeile mit der Zeichenfolge und zum Löschen dieser. Der w
Befehl in ed
speichert die geänderte Datei.
Antwort3
Eine andere Möglichkeit wäre, sed
durch zu ersetzen ed
und Ihre Befehle in einer Datei zu speichern. Wenn Sie beispielsweise ed_cmds
mit folgendem Inhalt erstellen:
%s/BASE_64/<expanded variable>/g
w
q
du könntest dann laufen
< ed_cmds ed FILE_NAME
und es würde die gewünschten Änderungen vornehmen, sodass $BASE_64
Sie anstelle der Einstellung die ed-Befehlsdatei erstellen würden.
Ed Erklärung
%
bedeutet, den Befehl auf jede Zeile der Datei anzuwendens/pat1/pat2/g
ersetzt Vorkommen vonpat1
durchpat2
undg
am Ende bewirkt, dass es dies für jede Übereinstimmung in der Zeile tut, nicht nur für die erstew
Schreiben Sie die Änderungen auf die Festplatteq
beenden (was sowieso passieren würde, wenn es EOF wird)
Natürlich könnten Sie Ihre sed
Befehle auch in eine Datei einfügen und verwenden -f
, aber wenn Sie das tun und die Datei an Ort und Stelle ändern möchten, können Sie auch verwenden, ed
anstatt eine temporäre Datei zu erstellen und sie wie sed -i
beschrieben zu verschieben.
Antwort4
Ich habe die Anweisungen schließlich sed
in einer Datei abgelegt
SEDCOMMANDS=`tempfile`
und rief
sed -f "$SEDCOMMANDS" -- "$FILE_NAME"
Das ist gut, wenn Sie nicht verwenden sed -i
. Wenn Sie die Datei an Ort und Stelle bearbeiten möchten, folgen Siehttps://unix.stackexchange.com/a/284188/149867und fügen Sie die entsprechenden ed
Anweisungen in eine Datei ein, gefolgt von w
und q
.