回答:
あなたはfileinput
モジュールを使うことができます:
import fileinput
for line in fileinput.input():
pass
fileinput
コマンドライン引数で指定されたファイル名として指定された入力のすべての行、または引数が指定されていない場合は標準入力をループします。
注:line
末尾の改行が含まれます。それを削除するにはline.rstrip()
import sys
for line in sys.stdin:
print(line)
これには最後に改行文字が含まれることに注意してください。最後に改行を削除するには、line.rstrip()
@ brittohalloranが言ったように使用します。
\r\n
行末
Pythonには組み込み関数input()
ともありraw_input()
ます。組み込み関数の下にあるPythonのドキュメントを参照してください。
例えば、
name = raw_input("Enter your name: ") # Python 2.x
または
name = input("Enter your name: ") # Python 3
これがPythonの学習の結果です。
import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."
Unixでは、次のような方法でテストできます。
% cat countlines.py | python countlines.py
Counted 3 lines.
WindowsまたはDOSでは、次のようにします。
C:\> type countlines.py | python countlines.py
Counted 3 lines.
cat
は冗長です。Unixシステムの正しい呼び出しはpython countlines.py < countlines.py
です。
readlines()
。ファイルオブジェクトは、メモリ内のすべてのデータを具体化せずに反復することを目的としています。
Pythonでstdinからどのように読みますか?
私はいくつかのコードゴルフチャレンジを実行しようとしていますが、すべてstdinから入力を取得する必要があります。Pythonでそれを取得するにはどうすればよいですか?
以下を使用できます。
sys.stdin
-ファイルのようなオブジェクト- sys.stdin.read()
すべてを読み取るための呼び出し。input(prompt)
-オプションのプロンプトを出力に渡し、標準入力から最初の改行まで読み取ります。より多くの行を取得するには、これを繰り返し行う必要があります。入力の最後にEOFErrorが発生します。(おそらくゴルフには最適ではありません。)Python 2では、これはrawinput(prompt)
です。open(0).read()
-Python 3では、組み込み関数open
はファイル記述子(オペレーティングシステムのIOリソースを表す整数)を受け入れ、0はの記述子ですstdin
。これは、ファイルのようなオブジェクトを返しますsys.stdin
。おそらくゴルフに最適です。Python 2では、これはio.open
です。open('/dev/stdin').read()
-と同様にopen(0)
、Python 2および3で機能しますが、Windows(またはCygwin)でも機能しません。fileinput.input()
-にリストされているすべてのファイルの行を反復子で返すか、指定されてsys.argv[1:]
いない場合はstdinを返します。のように使用し''.join(fileinput.input())
ます。どちらsys
とfileinput
当然のことながら、それぞれ、インポートする必要があります。
sys.stdin
Python 2および3、Windows、Unixと互換性のある簡単な例だけに指定する必要があるread
からsys.stdin
:たとえば、標準入力にあなたパイプデータならば、
$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo
これsys.stdin
がデフォルトのテキストモードであることがわかります。
>>> import sys
>>> sys.stdin
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>
ファイルがあるとするとinputs.txt
、そのファイルを受け入れて書き戻すことができます。
python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
これは、組み込み関数input
(raw_input
Python 2で使用)との2 つの方法を使用して、完全に簡単に複製できるデモsys.stdin
です。データは変更されていないため、処理は操作ではありません。
まず、入力用のファイルを作成しましょう。
$ python -c "print('foo\nbar\nbaz')" > inputs.txt
そして、すでに見たコードを使用して、ファイルが作成されたことを確認できます。
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz
sys.stdin.read
Python 3からのヘルプは次のとおりです。
read(size=-1, /) method of _io.TextIOWrapper instance
Read at most n characters from stream.
Read from underlying buffer until we have n characters or we hit EOF.
If n is negative or omitted, read until EOF.
input
(raw_input
Python 2の場合)組み込み関数はinput
、標準入力から取り除かれる改行まで読み取ります(print
デフォルトでは改行を追加する補完)。これは、EOF(ファイルの終わり)を取得するまで発生し、その時点でが発生しEOFError
ます。
したがって、以下はinput
、Python 3(またはraw_input
Python 2)でstdinから読み取る方法です。つまり、stdindemo.pyというPythonモジュールを作成します。
$ python -c "print('try:\n while True:\n print(input())\nexcept EOFError:\n pass')" > stdindemo.py
そして、それを印刷して、期待どおりであることを確認しましょう。
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py
try:
while True:
print(input())
except EOFError:
pass
この場合もinput
、改行まで読み取り、基本的には行から取り除きます。print
改行を追加します。したがって、両方が入力を変更する一方で、変更はキャンセルされます。(したがって、それらは本質的にお互いの補完です。)
そして、input
ファイルの終わり文字を取得すると、EOFErrorが発生します。これを無視して、プログラムを終了します。
Linux / Unixでは、猫からパイプすることができます:
$ cat inputs.txt | python -m stdindemo
foo
bar
baz
または、stdinからファイルをリダイレクトすることもできます。
$ python -m stdindemo < inputs.txt
foo
bar
baz
モジュールをスクリプトとして実行することもできます:
$ python stdindemo.py < inputs.txt
foo
bar
baz
input
Python 3 の組み込みに関するヘルプは次のとおりです。
input(prompt=None, /)
Read a string from standard input. The trailing newline is stripped.
The prompt string, if given, is printed to standard output without a
trailing newline before reading input.
If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
On *nix systems, readline is used if available.
sys.stdin
ここでは、を使用してデモスクリプトを作成しsys.stdin
ます。ファイルのようなオブジェクトを反復する効率的な方法は、ファイルのようなオブジェクトをイテレータとして使用することです。この入力からstdoutに書き込むための補足的な方法は、単に次を使用することsys.stdout.write
です。
$ python -c "print('import sys\nfor line in sys.stdin:\n sys.stdout.write(line)')" > stdindemo2.py
印刷して、正しく表示されることを確認します。
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py
import sys
for line in sys.stdin:
sys.stdout.write(line)
そして入力をファイルにリダイレクトします:
$ python -m stdindemo2 < inputs.txt
foo
bar
baz
コマンドにゴルフ:
$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz
stdin
およびのファイル記述子はstdout
それぞれ0と1であるためopen
、Python 3に渡すこともできます(2ではなく、標準出力への書き込みには「w」が必要であることに注意してください)。
これがシステムで機能する場合、より多くの文字が削られます。
$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo
Python 2 io.open
もこれを行いますが、インポートにはより多くのスペースが必要です。
$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt
foo
bar
baz
1つのコメントは''.join(sys.stdin)
ゴルフを示唆していますが、実際にはsys.stdin.read()よりも長くなっています。さらに、Pythonはメモリ内に追加のリストを作成する必要があります(リストがstr.join
指定されていない場合に機能します)-対照的に:
''.join(sys.stdin)
sys.stdin.read()
一番上の答えは示唆しています:
import fileinput
for line in fileinput.input():
pass
しかし、sys.stdin
イテレータプロトコルを含むファイルAPIを実装しているので、これは次と同じです。
import sys
for line in sys.stdin:
pass
別の答えはこれを示唆しています。ちょうどあなたが通訳でそれを行うならば、あなたがする必要がありますことを覚えておいてくださいCtrl- dあなたは、LinuxやMacを使っている場合、またはCtrl- zWindows上で(後Enter工程へのファイル終了文字を送信するために)。また、その答えはprint(line)
- '\n'
最後にを追加する-をprint(line, end='')
代わりに使用することを示唆しています(Python 2の場合はが必要になりますfrom __future__ import print_function
)。
の実際のユースケースfileinput
は、一連のファイルを読み取るためのものです。
他の人が提案した答え:
for line in sys.stdin:
print line
は非常にシンプルでpythonicですが、スクリプトはEOFまで待機してから入力行の反復を開始することに注意してください。
これは、tail -f error_log | myscript.py
行が期待どおりに処理されないことを意味します。
このようなユースケースの正しいスクリプトは次のようになります。
while 1:
try:
line = sys.stdin.readline()
except KeyboardInterrupt:
break
if not line:
break
print line
更新
コメントから、python 2にのみバッファリングが含まれる可能性があることが明確になりました。その結果、print呼び出しが発行される前に、バッファがいっぱいになるかEOFになるのを待つことになります。
for line in sys.stdin:
パターンはしない EOFを待ちます。ただし、非常に小さなファイルでテストすると、応答がバッファリングされる場合があります。より多くのデータでテストして、中間結果を読み取ることを確認します。
print line
は3.1.3では目覚めませんが、目覚めprint(line)
ます。
を使用してすべての回答を基にsys.stdin
、少なくとも1つの引数が存在する場合は次のようにして引数ファイルから読み取り、そうでない場合は標準入力にフォールバックすることもできます。
import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin
for line in f:
# Do your stuff
どちらかとして使用します
$ python do-my-stuff.py infile.txt
または
$ cat infile.txt | python do-my-stuff.py
あるいは
$ python do-my-stuff.py < infile.txt
これにより、Pythonスクリプトはcat
、grep
やのような多くのGNU / Unixプログラムのように動作しますsed
。
argparse
簡単な解決策ですPythonバージョン2と3の両方と互換性のある例:
#!/usr/bin/python
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument('infile',
default=sys.stdin,
type=argparse.FileType('r'),
nargs='?')
args = parser.parse_args()
data = args.infile.read()
このスクリプトはさまざまな方法で実行できます。
1.使用 stdin
echo 'foo bar' | ./above-script.py
./above-script.py <<< 'foo bar'
2.ファイル名引数を使用する
echo 'foo bar' > my-file.data
./above-script.py my-file.data
3. stdin
特別なファイル名を使用する-
echo 'foo bar' | ./above-script.py -
add_argument('--in'
スクリプトにパイプ--in -
してコマンドラインに追加することもできます。PS in
は、変数/属性にあまり適していません。
in
変数の名前だけでなく、違法です。予約済みキーワードのargs.in.read()
ため、InvalidSyntaxエラーが発生しますin
。単純に名前を変更することができますinfile
:ドキュメント行うargparse Pythonのようなdocs.python.org/3/library/...
今のところ、このハックについて誰も言及していません。
python -c "import sys; set(map(sys.stdout.write,sys.stdin))"
python2ではあなたはset()
電話を切ることができますが、それはどちらの言葉でも
readlines
それを行に分割して使用するのjoin
ですか?あなたはただ書くことができますprint(sys.stdin.read())
write
返されNone
、セットのサイズが1(=len(set([None]))
)より大きくなることはないからです
stdinから読み取り、次のように入力を「データ」に格納できます。
data = ""
for line in sys.stdin:
data += line
data = sys.stdin.read()
、文字列の連結が繰り返されるという問題はありません。
読むからsys.stdin
、それだけにはWindows上でバイナリデータを読んで、あなたはので、特に注意する必要がsys.stdin
あり、テキストモードで開かれ、それが破損します\r\n
とそれらを置き換えます\n
。
解決策は、Windows + Python 2が検出された場合はモードをバイナリに設定し、Python 3ではを使用することsys.stdin.buffer
です。
import sys
PY3K = sys.version_info >= (3, 0)
if PY3K:
source = sys.stdin.buffer
else:
# Python 2 on Windows opens sys.stdin in text mode, and
# binary data that read from it becomes corrupted on \r\n
if sys.platform == "win32":
# set sys.stdin to binary mode
import os, msvcrt
msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
source = sys.stdin
b = source.read()
私が解決策で抱えている問題
import sys
for line in sys.stdin:
print(line)
stdinにデータを渡さない場合、永久にブロックされます。だからこそ、私はこの答えが大好きです。まずstdinにデータがあるかどうかを確認してから、それを読んでください。これは私がやったことです:
import sys
import select
# select(files to read from, files to write to, magic, timeout)
# timeout=0.0 is essential b/c we want to know the asnwer right away
if select.select([sys.stdin], [], [], 0.0)[0]:
help_file_fragment = sys.stdin.read()
else:
print("No data passed to stdin", file=sys.stderr)
sys.exit(2)
select
。または、stdinが遅いメディア(ネットワーク、CD、テープなど)上のファイルに接続されている場合にも問題が発生する可能性があります。「標準入力にデータを渡さないと、永久にブロックされます」とあなたは言った。ある問題は、私はそれがだと言うでしょう機能。ほとんどのCLIプログラム(例えばcat
)はこのように機能し、期待どおりに機能します。EOFは、入力の終わりを検出するために依存すべき唯一のものです。
パイプで接続されたソケットを介して読み取るためにこれを機能させるときに、いくつかの問題がありました。ソケットが閉じられると、アクティブなループで空の文字列を返し始めました。これが私の解決策です(私はLinuxでのみテストしましたが、他のすべてのシステムで機能することを願っています)
import sys, os
sep=os.linesep
while sep == os.linesep:
data = sys.stdin.readline()
sep = data[-len(os.linesep):]
print '> "%s"' % data.strip()
したがって、ソケットでリスニングを開始した場合、ソケットは適切に機能します(bashなど)。
while :; do nc -l 12345 | python test.py ; done
そして、あなたはそれをTelnetで呼び出すか、ブラウザに単にlocalhost:12345を指すようにすることができます
これに関して:
for line in sys.stdin:
私はpython 2.7(他の誰かの提案に従う)で非常に大きなファイルを試してみましたが、正確には上記の理由(長時間は何も起こらない)のため、お勧めしません。
私は少しPython的な解決策に終わりました(そしてそれはより大きなファイルで動作します):
with open(sys.argv[1], 'r') as f:
for line in f:
次に、スクリプトをローカルで実行できます。
python myscript.py "0 1 2 3 4..." # can be a multi-line string or filename - any std.in input will work
sys.stdin
、コマンドライン引数としてスクリプトに渡します。
sys.stdin
スクリプトにコマンドライン引数としてどのように渡すことができますか?引数は文字列で、ストリームはファイルのようなオブジェクトですが、同じではありません。
sys.stdin
、ファイルのようなオブジェクトです