1

次のコードを使用して、Pythonを使用してファイルでgrepを起動しようとしています。

def runProcess(self, cmd):
    p = subprocess.Popen(cmd, bufsize=16000, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    return iter(p.stdout.readline, b'')

問題は、起動するたびに異なる一致が得られることです。一部の行は、returnオブジェクトで単にスキップされます。バッファが上書きされたのと同じように。私はこれを機能させるためにサブプロセスで見つけたすべての方法を試しましたが、すべて同じ問題が発生します。

詳細については、シェルで直接grepコマンドをテストしましたが、完全に機能します。これが、関数にcmd引数として渡すものです。

['egrep', '-wi', '-nr', "'keyword1|keyword2|blabla'", 'test/match_inside.txt']

また、bufsizeにさまざまな値を使用してみました(cの値はありません)

4

2 に答える 2

2

代わりに次を呼び出すと、この問題は(私のテストでは)なくなります。

['egrep', '-wi', '-nr', 'keyword1|keyword2|blabla', 'test/match_inside.txt']

Popenのドキュメントは、shlex.split()が、コマンドライン引数を文字列のリストにする方法を示していることを示しています。彼らの例では、外側の引用符は個々の引数から削除されています。

編集:bashに精通していると、誤解を招く可能性があります。しかし、Bashは単なる別のスクリプト言語です。入力した場合

grep 'a|b|c' target.txt

bashは、新しいgrepプロセスを作成するためにオペレーティングシステムコール(Linuxではexecまたはいくつかのバリアント)を呼び出しています。Bashはそのコマンドを解析し、引用符を削除します。これらはgrepのオプションの一部ではなく、トークンをグループ化することで入力をbashスキャンするのに役立ちます。Grepにはパラメータの文字列配列(Cではargvが含まれます)が渡されるため、引数で引用符を囲む必要はありません。引数の構造とグループ化は、文字列配列によって作成されます。

使用する場合

"'keyword1|keyword2|blabla'"

Pythonでは、基本的に合格です

'keyword1|keyword2|blabla'

本当にgrepにのみ持たせたい場合は、完全な文字列としてgrepに移動します

keyword1|keyword2|blabla

argvのインデックス3(先行する引数の数に応じて)の文字列として。

于 2013-03-14T21:11:29.017 に答える
1

コメントすることはできませんが、自分自身が質問するのを止めることはできません。

なぜgrepPython内から実行するのですか?そしてサブプロセスで?? Pythonを使用している場合は、 PythonREを読むことを強くお勧めします。これはgrepよりもはるかに強力であり、全体として(私の意見では)理解と制御が容易です。

編集:質問は実用的です。理由を知りたい。

于 2013-03-14T21:13:09.380 に答える