web-dev-qa-db-ja.com

ファイルから読み取る、またはSTDIN

コマンドラインで指定された引数を解析するためにgetoptを使用するコマンドラインユーティリティを作成しました。また、grep、cutなどの他のユーティリティにあるように、ファイル名をオプションの引数にしたいので、次のように使用したいと思います。

tool -d character -f integer [filename]

以下を実装するにはどうすればよいですか?

  • ファイル名が指定されている場合は、ファイルから読み取ります。
  • ファイル名が指定されていない場合は、STDINから読み取ります。
58
Ryan R. Rosario

最も簡単な言葉で:

import sys
# parse command line
if file_name_given:
    inf = open(file_name_given)
else:
    inf = sys.stdin

この時点で、infを使用してファイルから読み取ります。ファイル名が指定されたかどうかに応じて、指定されたファイルまたは標準入力から読み取ります。

ファイルを閉じる必要があるとき、これを行うことができます:

if inf is not sys.stdin:
    inf.close()

ただし、ほとんどの場合、sys.stdinを終了しても問題ありません。

58
Greg Hewgill

fileinput モジュールはあなたが望むことをするかもしれません-非オプション引数がargsにあると仮定すると:

_import fileinput
for line in fileinput.input(args):
    print line
_

argsが空の場合、fileinput.input()はstdinから読み取ります。それ以外の場合、Perlのwhile(<>)と同様の方法で、各ファイルから順番に読み取ります。

74
SimonJ

コンテキストマネージャーを使用する一般的なイディオムが好きですが、(あまりにも)些細な解決策は、withステートメントを終了したときに_sys.stdin_を閉じることになります。

この回答 から借用して、回避策を示します。

_import sys
import contextlib

@contextlib.contextmanager
def _smart_open(filename, mode='Ur'):
    if filename == '-':
        if mode is None or mode == '' or 'r' in mode:
            fh = sys.stdin
        else:
            fh = sys.stdout
    else:
        fh = open(filename, mode)
    try:
        yield fh
    finally:
        if filename is not '-':
            fh.close()

if __== '__main__':
    args = sys.argv[1:]
    if args == []:
        args = ['-']
    for filearg in args:
        with _smart_open(filearg) as handle:
            do_stuff(handle)
_

os.dup()と似たもの を達成できると思いますが、それを行うために作成したコードは、より複雑でより魔法のようになりましたが、上記はやや不格好ですが、非常に簡単です。

16
tripleee

Pythonのwithステートメントを使用するには、次のコードを使用できます。

import sys
with open(sys.argv[1], 'r') if len(sys.argv) > 1 else sys.stdin as f:
    # read data using f
    # ......
11
Roun

Stdinから読み取る必要があることを示すインジケータとして「-」を使用することを好みます。これはより明確です。

import sys
with open(sys.argv[1], 'r') if sys.argv[1] is not "-" else sys.stdin as f:
    pass # do something here
9
Phil L.

直接的な答えではなく、関連しています。

通常、pythonスクリプトを記述する場合、argparseパッケージを使用できます。この場合、次のように使用できます。

parser = argparse.ArgumentParser()
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)

「?」 1つの引数は、可能であればコマンドラインから消費され、単一のアイテムとして生成されます。コマンドライン引数が存在しない場合、デフォルトの値が生成されます。

そして、ここでデフォルトをsys.stdinに設定します;

そのため、ファイルがある場合はそれを読み取り、そうでない場合はstdinからの入力を受け取ります。「注:上記の例では位置引数を使用しています」

詳細については、 https://docs.python.org/2/library/argparse.html#nargs

5
Medhat

何かのようなもの:

if input_from_file:
    f = open(file_name, "rt")
else:
    f = sys.stdin
inL = f.readline()
while inL:
    print inL.rstrip()
    inL = f.readline()
1
GreenMatt