

以下のコードではgrepを用いて配列animalの中からtest.txt内に存在するものだけ  
を出力したいのですが、おそらくgrepの出力結果を変数にうまく格納できていないのか、何度やってもエラーが発生してしまいます。解決方法がわからないため、教えていただきたいです。

[code]

    # coding: UTF-8                                                                                                                                                                                                                                                                                           
    import subprocess                                                                                                                                                                                                                                                                                                                                                                                                                                    
    
    animal=["dog","cat","horse","pig","bird"]
    WORD=[]
    cmd="grep -c {} test.txt"                                                                                                                                                                                                                                                                                  
    
    for i in range(len(animal)):                                                                                                                                                                                                                                                                                   
      c=subprocess.check_output(cmd.format(animal[i]).split())                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           
    
      if int(c) > 0:                                                                                                                                                
        WORD.append(animal[i])                                                                                                                                               
    
    for i in range(len(WORD)):                                                                                                                               
      print("WORD[i]=%s" % WORD[i])
    
[/code]

以下のようなエラーが発生しました。

[code]

    Traceback (most recent call last):
      File "test.py", line 8, in <module>
        c=subprocess.check_output(cmd.format(animal[i]).split())
      File "C:\Users\aveni\AppData\Local\Programs\Python\Python38-32\lib\subprocess.py", line 411, in check_output
        return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
      File "C:\Users\aveni\AppData\Local\Programs\Python\Python38-32\lib\subprocess.py", line 512, in run
        raise CalledProcessError(retcode, process.args,
    subprocess.CalledProcessError: Command '['grep', '-c', 'pig', 'test.txt']' returned non-zero exit status 1.
    
[/code]


CC BY-SA 4.0
2020-01-10T17:22:34.410
62143
2020-01-11T14:55:02.807
2020-01-11T05:28:17.167
3060
37132
question
python python3 grep
Pythonでgrepコマンドを実行する際に変数展開する方法


`subprocess.check_output`は実行したコマンドの終了コード（exit
status）が0以外の場合に`CalledProcessError`を出します。`grep`は探している文字列がマッチしたときだけ終了コードが0になります。`check_output`の代わりに`run`をつかった場合はこうなります。

[code]

    # -*- coding: utf-8 -*-
    import subprocess
    
    animal = ["dog", "cat", "horse", "pig", "bird"]
    WORD = []
    cmd = "grep -c {} test.txt"
    
    for ani in animal:
        c = subprocess.run(cmd.format(ani).split(), capture_output=True)
        if int(c.stdout) > 0:
            WORD.append(ani)
    
    for w in WORD:
        print("WORD[i]=%s" % w)
    
[/code]

grepコマンドで文字列があるかどうかを判別するだけなら、終了コード（c.returncode）を使うほうが良い書き方だと思います。


CC BY-SA 4.0
2020-01-10T17:51:04.883
62146
2020-01-10T17:51:04.883
37406
62143
answer


subprocess.check_output() を使う場合には
[subprocess.CalledProcessError](https://docs.python.org/3.7/library/subprocess.html#subprocess.CalledProcessError)
を捕捉する事になります。

それから、これは本題とは関係がありませんが、検索語に空白文字(TAB
やスペースなど)が含まれている場合、質問欄のコードではエラーが発生してしまいます。以下では検索語をシングルクォートで囲み、`subprocess.check_output()`
で `shell=True` を指定しています。

[code]

    import subprocess
    
    animal = ['dog', 'cat', 'horse', 'pig', 'bird', 'wild boar']
    WORD = []
    cmd = r"grep -c '{}' test.txt"
    
    for name in animal:
      try:
        c = subprocess.check_output(cmd.format(name), shell=True)
      except subprocess.CalledProcessError as ex:
        if ex.returncode == 1:   ## None match
          c = 0 ## c = ex.output
        elif ex.returncode == 2: ## Error occurred
          print(ex)
          break
    
      if int(c) > 0:
        WORD.append(name)
    
    for i in range(len(WORD)):
      print(f'WORD[{i}] = {WORD[i]}')
    
[/code]


CC BY-SA 4.0
2020-01-11T14:49:35.127
62169
2020-01-11T14:55:02.807
2020-01-11T14:55:02.807
62143
answer