【问题标题】:How to make a python script "pipeable" in bash?如何在 bash 中使 python 脚本“可管道化”?
【发布时间】:2011-05-24 17:13:54
【问题描述】:

我写了一个脚本,我希望它在 bash 中是 pipeable 的。比如:

echo "1stArg" | myscript.py

有可能吗?怎么样?

【问题讨论】:

标签: python pipe


【解决方案1】:

看这个简单的echo.py

import sys

if __name__ == "__main__":
    for line in sys.stdin:
        sys.stderr.write("DEBUG: got line: " + line)
        sys.stdout.write(line)

运行:

ls | python echo.py 2>debug_output.txt | sort

输出:

echo.py
test.py
test.sh

debug_output.txt 内容:

DEBUG: got line: echo.py
DEBUG: got line: test.py
DEBUG: got line: test.sh

【讨论】:

  • 循环的编写方式 (while True...) 既不正确,也肯定不是 Pythonic。事实上,一个空的输入行将打破循环。一个简单而标准的解决方案是使用for line in sys.stdin 读取标准输入。另外,最初的line = '' 完全是多余的。
  • 太棒了!我冒昧地使用标准的 4 个空格(参见 PEP 8)而不是您使用的原始 2 个空格来缩进您的代码。
【解决方案2】:

我将用一个 grep 示例来补充其他答案,该示例使用fileinput 来实现 UNIX 工具的典型行为:1)如果未指定参数,它会从标准输入读取数据; 2) 许多文件可以指定为参数; 3) - 的单个参数表示标准输入。

import fileinput
import re
import sys

def grep(lines, regexp):
    return (line for line in lines if regexp.search(line))

def main(args):
    if len(args) < 1:
        print("Usage: grep.py PATTERN [FILE...]", file=sys.stderr)
        return 2 
    regexp = re.compile(args[0])
    input_lines = fileinput.input(args[1:])
    for output_line in grep(input_lines, regexp):
        sys.stdout.write(output_line)

if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

例子:

$ seq 1 20 | python grep.py "4"
4
14

【讨论】:

    【解决方案3】:

    在您的 Python 脚本中,您只需 read from stdin

    【讨论】:

      【解决方案4】:

      从标准输入读取的所有内容都是“可管道化的”。 Pipe 只是将前一个程序的标准输出重定向到后者。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-19
        • 1970-01-01
        • 2018-05-07
        • 2016-04-10
        • 1970-01-01
        • 1970-01-01
        • 2011-12-17
        • 1970-01-01
        相关资源
        最近更新 更多