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

を仕事をしたい正確にどのように機能していません。SEDが、私はそれが、これは私が問題が何であるかわからないエラー</p> <blockquote> <p>ExecutionError: sed: -e expression #1, char 0: no previous regular expression</p> </blockquote> <p>を与える

上記はPythonスクリプトで使用されています。

+0

私はサブプロセスを使用することができますが、私はここで何が不足しているのか知りたいのです。 – user2939055

+0

コマンドラインからうまく動作します。私はここでPythonが問題かもしれないと思う。 – miken32

+0

@ miken32:これはPythonではなく、 'bash'の誤用です。これはコマンドラインからはうまく動作しません: 'new_val = 9 && old_val = 3 sed"/$ old_val/$ new_val/g "<(エコー" 1234567890 ")' – ShadowRanger

答えて

2

変更はそれがに:

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

変数の割り当てはsedとは別の声明にする必要があります。ステートメントの先頭に変数代入を置くと、子プロセスによって継承される環境変数のみが設定されます。しかし、元のシェルで変数を展開する必要があるので、sedコマンドを実行する前に変数を設定する必要があります。

-1

実際に私は、各変数を一重引用符で囲み、一重引用符をエスケープして、何かを見つけました。

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

は変数ではなく、sedを展開するシェルに依存している:

+0

ソリューションコードの説明/提供はできますか?私は、一重引用符がここで助けになるという明白な方法は見ていません(bash変数の補間を避けるためにそれらを使うことはできますが、 'sed'は' $ '名リテラル文字列として扱います)。 – ShadowRanger

0

あなたの問題があることです。しかし、コマンド接頭辞を介して変数を設定するのは、bashではなくコマンドの環境にのみ影響します。したがって、old_valではないは文字列補間の目的で定義されています。 bash reference manualあたり(強調追加):

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.

sedは、独自の環境からold_valを読み取ろうとしましたのであれば、それは正しい値を見ることになります。しかし、sedが受け取っているのは、bash補間がold_val(それはsedの場合のみ)を参照していないので、s//9/gである補間後の文字列が渡されます。修正するには

は、別々のコマンドではなく、sed接頭辞として割り当てを行うことで、bashで変数を設定します。

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

以上正確に、あなたは本当に(それはへの容易な/危険だshell=Trueに頼らないようにする必要があり悪用)。あなたがsedを使用しなければならない場合でも、あなたがシェルを使用していたすべてのものは、Pythonの層で行うことができます。

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') 

これは、同じ動作を持っている(/etc/squidで動作し、あなたが勝ったように、修飾されていないファイル名を渡します深くネストされたディレクトリにたくさんのファイルがある場合、新しいコマンドラインの長さの問題があります)。

もちろん、the fileinput moduleを使って、sedの作業をPythonでも行えます。それはちょうどsedのような場所にファイルを編集することを特徴とします(しかし、ファイルが意味のあるサイズであれば多少遅くなります)。

関連する問題