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

fileinput ライブラリは stdin があれば 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()

このソリューションを初めて見たのはここ

関連情報