如何使 python 程序表现得像正确的 unix 工具?

如何使 python 程序表现得像正确的 unix 工具?

我手头上有一些 Python 脚本,我正在努力重写它们。我和他们所有人都有同样的问题。

对我来说,如何编写程序以使它们表现得像正确的 UNIX 工具一样并不明显。

因为这

$ cat characters | progname

和这个

$ progname characters

应该产生相同的输出。

我能在 Python 中找到的最接近的东西是 fileinput 库。不幸的是,我真的不知道如何重写我的 Python 脚本,所有脚本都如下所示:

#!/usr/bin/env python 
# coding=UTF-8

import sys, re

for file in sys.argv[1:]:
    f = open(file)
    fs = f.read()
    regexnl = re.compile('[^\s\w.,?!:;-]')
    rstuff = regexnl.sub('', fs)
    f.close()
    print rstuff

如果有 stdin,则 fileinput 库处理 stdin;如果有文件,则处理文件。但它迭代单行。

import fileinput
for line in fileinput.input():
    process(line)

我真的不明白。我想如果您正在处理小文件,或者您没有对文件做太多操作,那么这可能看起来很明显。但是,就我的目的而言,这比简单地打开整个文件并将其读入字符串要慢得多,如上所述。

目前我运行上面的脚本就像

$ pythonscript textfilename1 > textfilename2

但我希望能够在管道中运行它(及其兄弟),例如

$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2

答案1

检查文件名是否作为参数给出,否则从中读取sys.stdin.

像这样的东西:

if len(sys.argv) > 0:
   f = open(sys.argv[1])
else:
   f = sys.stdin 

它与 Mikel 的答案类似,只是它使用了该sys模块。我想,如果他们把它放在那里,那一定是有原因的……

答案2

为什么不只是

files = sys.argv[1:]
if not files:
    files = ["/dev/stdin"]

for file in files:
    f = open(file)
    ...

答案3

事实证明,我最喜欢的做法是......(这取自一个不错的 Linux 小博客,名为先驱者山谷

#!/usr/bin/env python

import argparse, sys

parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename:
    string = open(args.filename).read()
elif not sys.stdin.isatty():
    string = sys.stdin.read()
else:
    parser.print_help()

我最喜欢这个的原因是,正如博主所说,如果不小心调用而没有输入,它只会输出一条愚蠢的消息。它也很好地融入了我现有的所有 Python 脚本中,因此我已经将它们全部修改以包含它。

答案4

我正在使用这个解决方案,它的作用就像一个魅力。实际上我在脚本调用中使用不带口音的小写并删除给定字符串中的重音符号

argument = sys.argv[1:] if len(sys.argv) > 1 else sys.stdin.read()

我想我第一次看到这个解决方案是这里

相关内容