2017-02-23 2 views
0
('cd /etc/squid/ && new_val=9 && old_val=3 && sed -i "s/$old_val/$new_val/g" *.conf') 

das gibt mir einen Fehlermit Variablen Sed ist nicht genau arbeiten, wie ich es

ExecutionError: sed: -e expression #1, char 0: no previous regular expression

Ich bin nicht sicher, was das Problem ist, arbeiten will.

Das obige wird in einem Python-Skript verwendet.

+0

Ich weiß, ich subprocess verwenden könnte, aber ich will wissen, was ich hier vermisst .. – user2939055

+0

Funktioniert bei mir von der Kommandozeile in Ordnung. Ich vermute, Python könnte hier das Problem sein. – miken32

+0

@ miken32: Es ist nicht Python, es ist der Missbrauch von 'bash'.Es funktioniert nicht gut von der Kommandozeile, einfache Repro: 'new_val = 9 && alt_val = 3 sed" s/$ alt_val/$ new_val/g "<(echo" 1234567890 ")' – ShadowRanger

Antwort

2

Ändern Sie es an:

('cd /etc/squid/ && new_val=9 && old_val=3 && sed -i "s/$old_val/$new_val/g" *.conf') 

Die variable Zuordnung muss von sed eine gesonderte Erklärung sein. Wenn Sie eine Variablenzuweisung am Anfang einer Anweisung platzieren, wird nur eine Umgebungsvariable festgelegt, die vom untergeordneten Prozess geerbt wird. Sie müssen die Variable jedoch durch die ursprüngliche Shell erweitern. Daher müssen Sie die Variable vor dem Ausführen des Befehls sed festlegen.

-1

Tatsächlich fand ich etwas, das funktionierte, indem ich jede der Variablen in einfache Anführungszeichen setzte und die einfachen Anführungszeichen entnahm.

+0

Können Sie den Lösungscode erklären/bereitstellen? Ich sehe keine offensichtliche Möglichkeit, dass die einfachen Anführungszeichen hier helfen würden (Sie könnten sie verwenden, um die variable Interpolation von Bash zu vermeiden, aber off hand glaube ich nicht, dass sed es für Sie tut, wenn es die $ Namen erhält , behandelt sie nur als wörtliche Zeichenfolgen). – ShadowRanger

0

Ihr Problem ist, dass:

old_val=3 sed "s/$old_val/$new_val/g" 

auf der Schale setzt die Variablen zu erweitern, nicht sed. Das Festlegen von Variablen über Befehlspräfix wirkt sich jedoch nur auf die Umgebung des Befehls aus, nicht auf die Bash. old_val ist also , nie, das für die Stringinterpolation definiert ist. Pro die bash reference manual (Hervorhebung hinzugefügt):

The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described in Shell Parameters. These assignment statements affect only the environment seen by that command.

Also, wenn sed versuchte old_val aus seiner eigenen Umgebung zu lesen wäre es um den richtigen Wert zu sehen. Aber was sed empfängt, ist die Post-Interpolation-Zeichenfolge übergeben, die s//9/g ist, da Bash-Interpolation old_val (das nur für sed existiert) nicht sehen.

Um dies zu beheben, wird die Variable in bash gesetzt durch die Zuordnung als separater Befehl ausgeführt wurde, kein sed Präfix:

('cd /etc/squid/ && new_val=9 && old_val=3 && sed -i "s/$old_val/$new_val/g" *.conf') 

Oder richtiger: Sie sollten wirklich auf shell=True vermeiden verlassen (es ist gefährlich/leicht zu Missbrauch). Auch wenn Sie sed, all die Dinge, die Sie wurden mit dem Shell für können an der Python-Schicht erfolgen verwenden müssen:

import os 

# Get the (unqualified) names of all the entries with the desired name 
files = [f for f in os.listdir('/etc/squid') if f.endswith('.conf')] 
# Run w/o shell=True, in list form, letting Python handle the working directory 
# and variable formatting 
subprocess.Popen(['sed', '-i', 's/{}/{}/g'.format(old_val, new_val)] + files, cwd='/etc/squid') 

Dies hat das gleiche Verhalten (arbeitet in /etc/squid, und übergibt die unqualifizierten Dateinamen so gewann man Wenn sich viele Dateien in einem tief verschachtelten Verzeichnis befinden, treten keine Probleme mit der Befehlszeilenlänge auf.

Natürlich könnten Sie noch weiter gehen und einfach the fileinput module verwenden, um die Arbeit von sed in Python zu erledigen; Es bietet die Bearbeitung von Dateien an Ort und Stelle wie sed (obwohl es wahrscheinlich etwas langsamer sein wird, wenn die Dateien eine sinnvolle Größe haben).

Verwandte Themen