20

CLIスクリプトがあり、ファイルからデータを読み取ってほしい。それは2つの方法でそれを読むことができるはずです:

  • cat data.txt | ./my_script.py
  • ./my_script.py data.txt

grep-たとえば、少し似ています。

私が知っていること:

  • sys.argv引数とoptparseオプションを簡単に読みましょう。
  • sys.stdinパイプされたデータを読み取らせてください
  • fileinput全プロセスを自動化する

不運にも:

  • usingfileinputは、stdinと任意の引数を入力として使用します。そのため、ファイル名ではないオプションを開こうとするため、使用できません。
  • sys.stdin.readlines()正常に動作しますが、データをパイプ処理しないと、入力するまでハングしますCtrl + D
  • stdin常にTrueブールコンテキストであるため、「stdinに何もない場合は、argsのファイルから読み取る」を実装する方法がわかりません。

可能であれば、これを行うためのポータブルな方法が欲しいです。

4

6 に答える 6

20

Argparseを使用すると、これをかなり簡単に実行できoptparseます。互換性の問題がない限り、Argparseを使用する必要があります。

コードは次のようになります。

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--input', type = argparse.FileType('r'), default = '-')

これで、コマンドライン引数を解析するパーサーができました。ファイルが見つかった場合はファイルを使用し、見つからない場合は標準入力を使用します。

于 2010-02-15T10:26:15.570 に答える
12

非ファイル名引数を必要に応じて処理するため、オプション以外の引数の配列になり、その配列をパラメーターとして次のように渡しますfileinput.input()

import fileinput
for line in fileinput.input(remaining_args):
    process(line)
于 2010-02-15T10:32:30.960 に答える
9

UNIX / Linuxの場合、データがパイプインされているかどうかを確認するには、os.isatty(0)

$ date | python -c "import os;print os.isatty(0)"
False
$ python -c "import os;print os.isatty(0)"
True

Windowsに相当するものがあるかどうかはわかりません。

編集 OK、私はウィンドウズXPのpython2.6でそれを試しました

C:\Python26>echo "hello" | python.exe -c "import os;print os.isatty(0)"  
False

C:\Python26> python.exe -c "import os;print os.isatty(0)"  
True

だから多分それはすべてが窓にとって絶望的ではない

于 2010-02-15T10:00:54.570 に答える
4

私は初心者なので、これは良い答えではないかもしれませんが、同じことをしようとしています(コマンドラインで1つ以上のファイルを許可し、それ以外の場合はデフォルトでSTDINに設定します)。

私がまとめた最後のコンボ:

parser = argparse.ArgumentParser()
parser.add_argument("infiles", nargs="*")
args = parser.parse_args()

for line in fileinput.input(args.infiles):
    process(line)

これは、名前付き引数を必要とせずに、1つのエレガントなパッケージですべての目的の動作を取得する唯一の方法のようです。UNIXコマンドがそのように使用されるのと同じように:

cat file1 file2
wc -l < file1

いいえ:

cat --file file1 --file file2

私が最良の答えを得ていることを確認するために、ベテランの慣用的なPythonistasからのフィードバック/確認をいただければ幸いです。この完全な解決策が他のどこにも言及されていないのを見たことがありません。断片だけです。

于 2013-02-01T19:33:31.327 に答える
3

が何かに接続されているかどうかを検出する信頼できる方法はなくsys.stdin、適切でもありません(たとえば、ユーザーがデータを貼り付けたい場合)。引数としてファイル名の存在を検出し、見つからない場合はstdinを使用します。

于 2010-02-15T09:46:03.550 に答える
2

この関数を使用して、入力がパイプラインからのものであるかどうかを検出できます。

sys.stdin.isatty()

入力がパイプラインからのものである場合はfalseを返し、それ以外の場合はtrueを返します。

于 2012-07-11T11:32:10.123 に答える