Grep странно исключает пустые строки из вывода

На самом деле вы не выполняете команду bash . Вы запускаете исполняемый файл напрямую и передаете ему аргументы.

Попробуйте следующий сценарий, чтобы увидеть, что происходит:

import subprocess
p = subprocess.Popen(["echo", "a", "b", "|", "rev"], stdout=subprocess.PIPE)
print p.communicate()

Результатом будет:

('a b | rev\n', None)

Перенаправления не происходит, знак "|" передается буквально. То есть, как если бы вы набрали find ... \ | параллельно ... . Таким образом ошибка.

Есть два способа исправить это.

  • Простой способ: передать shell = True в subprocess.Popen . Это пропустит его через оболочку со всем, что влечет за собой. Если вы это сделаете, вам также необходимо передать строку вместо массива:

     import subprocess 
    p = subprocess.Popen ("echo ab | rev", stdout = subprocess.PIPE, shell = True ) 
    print p.communicate () 
     
     # Результат: ('ba \ n', Нет) 
     

    Если вы сделаете это, будьте очень осторожны с подстановкой аргументов в вашу строку .

  • Надежный способ: открыть два процесса с помощью Python и соединить их по конвейеру.

     import subprocess 
     # Первая команда 
    p1 = subprocess.Popen (["echo", "a", "b"], stdout = subprocess.PIPE) 
     # Вход второй команды связан с выходом первой 
    p2 = subprocess.Popen (["rev"], stdin = p1.stdout, stdout = subprocess.PIPE) 
     # Прочитать из p2, чтобы получить output 
    print p2.communicate () 
     
     # Result: ('ba \ n', None) 
     

    Это более надежно и не порождает дополнительную оболочку, но, с другой стороны, она больше печатает.Если вы сделаете это, то обратите внимание, что никакая замена оболочки не происходит . В вашем случае это не похоже, что вам это нужно, но если вы хотите использовать, скажем, ~ , вам придется получить его через Python (например, os.getenv ( «ДОМ») ).

1
16.12.2018, 05:45
2 ответа

Второй ищет строки, содержащие хотя бы один символ, и поэтому не находит пустые строки, в которых нет символов. Если вы хотите оба, попробуйте следующее:

grep -e ^[^#] -e ^$ /etc/apache2/apache2.conf
4
29.04.2021, 00:00
grep -v ^#
  • исключить строки, которые не начинаются с#
  • пустые строки не начинаются с #, поэтому ex не включены

тогда как

grep ^[^#]
  • включают строки, начинающиеся с любого символа, кроме#
  • пустые строки не начинаются с любого символа, поэтому в не включены
2
29.04.2021, 00:00

Теги

Похожие вопросы