ඔබ stdin වෙතින් කියවන්නේ කෙසේද?


1483

මම කේත ගොල්ෆ් අභියෝග කිහිපයක් කිරීමට උත්සාහ කරමි , නමුත් ඒ සියල්ලටම ආදානය ලබා ගත යුතුය stdin. මම එය පයිතන් වලින් ලබා ගන්නේ කෙසේද?

Answers:


955

ඔබට fileinputමොඩියුලය භාවිතා කළ හැකිය :

import fileinput

for line in fileinput.input():
    pass

fileinput විධාන රේඛා පරාමිතීන්හි දක්වා ඇති ගොනු නාමයන් ලෙස දක්වා ඇති ආදානයේ ඇති සියලුම රේඛා හරහා හෝ තර්ක ලබා නොදුනහොත් සම්මත ආදානය හරහා ලූප වේ.

සටහන: lineපසුපස නව රේඛාවක් අඩංගු වේ; එය ඉවත් කිරීමට භාවිතා කරන්නline.rstrip()


2
OrBorislavStoilov තවද මෙම පිළිතුර නිවැරදිව ප්‍රශ්නයට පිළිතුරු සපයයි: "හෝ තර්ක ඉදිරිපත් කර නොමැති නම් සම්මත ආදානය".
ඩියට්මාර්

1
ප්‍රලේඛනයෙහි දැක්වෙන්නේ එය stdin වෙත ආපසු යන බවයි: "මෙය sys.argv හි ලැයිස්තුගත කර ඇති සියලුම ලිපිගොනු වලට වඩා වෙනස් වේ [1:], ලැයිස්තුව හිස් නම් sys.stdin වෙත පෙරනිමිය. ගොනු නාමයක් '-' නම්, එය ද ප්‍රතිස්ථාපනය වේ. sys.stdin විසින් විකල්ප ගොනු නාම ලැයිස්තුවක් සඳහන් කිරීමට, එය ආදානය () සඳහා පළමු තර්කය ලෙස යොමු කරන්න. තනි ගොනු නාමයක් ද අවසර දෙනු ලැබේ.
ආර්ලෝ

723

එය කිරීමට ක්‍රම කිහිපයක් තිබේ.

  • sys.stdinගොනුව වැනි වස්තුවක් කාර්යයන් මත ඔබ ඇමතිය හැකි වේ readහෝ readlines, ඔබට සියල්ල කියවීමට අවශ්ය නම් හෝ, ඔබට සියල්ල කියවා ස්වයංක්රීයව නව පේළියකට යොමු කිරීමේ අක්ෂරය මගින් එය බෙදීමට අවශ්ය. (මෙය ක්‍රියාත්මක වීමට ඔබට අවශ්‍යය import sys.)

  • ඔබට අවශ්ය නම් මතක් ආදානය සඳහා පරිශීලක, ඔබ භාවිතා කළ හැකිය raw_inputPython 2.X, සහ පමණක් inputPython 3.

  • ඔබට සැබවින්ම විධාන රේඛා විකල්ප කියවීමට අවශ්‍ය නම්, ඔබට ඒවා sys.argv ලැයිස්තුව හරහා ප්‍රවේශ විය හැකිය .

පයිතන් හි I / O පිළිබඳ මෙම විකිබුක් ලිපිය ප්‍රයෝජනවත් සඳහනක් ලෙස ඔබ බොහෝ විට සොයා ගනු ඇත .


455
import sys

for line in sys.stdin:
    print(line)

මෙයට අවසානයේ නව රේඛා අක්ෂරයක් ඇතුළත් වන බව සලකන්න. නව line.rstrip()රේඛාව අවසානයේ ඉවත් කිරීමට @ බ්‍රිටෝහෝලෝරන් පැවසූ පරිදි භාවිතා කරන්න .


7
line.rstrip ('\ n'), එසේ නොවුවහොත් එය සියලු
සුදු

මෙම ක්‍රමය භාවිතා කරමින්, ආදාන ප්‍රවාහය අවසන් වන විට අප දැන ගන්නේ කෙසේද? අවසාන පේළිය හැරුණු විට සෑම පේළියකටම පසු කොමාව එක් කිරීමට මට අවශ්‍යය .
ඇබ්බැහි වූ

මට ලැබෙන්නේ: TypeError: 'FileWrapper' වස්තුව නැවත යෙදිය නොහැක.
ඩියාගෝ ක්වීරෝස්

@avp මෙය \r\nරේඛීය අවසානයන් සමඟ නිවැරදිව කටයුතු නොකරනු ඇත
josch

230

පයිතන් තුළ ගොඩනංවන ලද කාර්යයන් input()raw_input()ඇත. බිල්ට් කාර්යයන් යටතේ පයිතන් ප්‍රලේඛනය බලන්න .

උදාහරණයක් වශයෙන්,

name = raw_input("Enter your name: ")   # Python 2.x

හෝ

name = input("Enter your name: ")   # Python 3

7
මෙය තනි පේළියක් කියවන අතර එය ඇත්ත වශයෙන්ම OP විමසූ දෙය නොවේ. මම ප්‍රශ්නය අර්ථ දක්වන්නේ “විවෘත ලිපිගොනු හසුරුවක සිට ඊඕඑෆ් දක්වා පේළි පොකුරක් කියවන්නේ කෙසේද?”
ත්‍රිත්ව

4
යතුරුපුවරුවකින් ආදානය කියවීමට OP ඉල්ලන්නේ නැත, තරඟකාරී අවස්ථාවකදී සාමාන්‍යයෙන් තරඟකරුවන්ට ලබා දෙන stdin වෙතින් කියවීමට ඔහු ඉල්ලා සිටී.
chrisfs

මට අවශ්‍ය වූයේ මෙයයි, ගූගල් මාව මෙහි ගෙනාවා. සිත්ගන්නාසුලු කරුණක් නම් මම rfid ටැග්, දිවා කාලය, දත්ත සමුදායන් කේත කිරීමට සමත් වූ නමුත් පරිශීලකයාගේ ආදානය කියවීමට කිසි විටෙකත් කරදර නොවූ lol
clockw0rk

207

ඉගෙනීමේ පයිතන් වෙතින් මෙන්න :

import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."

යුනික්ස් හි, ඔබට මෙවැනි දෙයක් කිරීමෙන් එය පරීක්ෂා කළ හැකිය:

% cat countlines.py | python countlines.py 
Counted 3 lines.

වින්ඩෝස් හෝ ඩොස් හි, ඔබ කරන්නේ:

C:\> type countlines.py | python countlines.py 
Counted 3 lines.

4
පයිතන්හි රේඛා ගණනය කිරීම සඳහා වඩාත් මතක කාර්යක්ෂම (හා සමහර විට වේගවත්) ක්‍රමයක් මෙන්න : print(sum(chunk.count('\n') for chunk in iter(partial(sys.stdin.read, 1 << 15), ''))). බලන්නwc-l.py
jfs

11
මෙහි භාවිතය catඅතිරික්තය. යුනික්ස් පද්ධති සඳහා නිවැරදි ආයාචනය වන්නේ python countlines.py < countlines.py.
istepaniuk

12
පරිශීලකයින් භාවිතා කිරීමට යොමු කිරීමේදී "පයිතන් ඉගෙනීම" වැරදිය readlines(). ගොනු වස්තූන් අදහස් කරන්නේ මතකයේ ඇති සියලුම දත්ත ද්‍රව්‍යකරණය නොකර නැවත සැකසීමට ය.
ආරොන් හෝල්

123

පයිතන්හි stdin වෙතින් ඔබ කියවන්නේ කෙසේද?

මම කේත ගොල්ෆ් අභියෝග කිහිපයක් කිරීමට උත්සාහ කරමි, නමුත් ඒ සියල්ලටම අවශ්‍ය වන්නේ ආදානය stdin වෙතින් ලබා ගැනීමයි. මම එය පයිතන් වලින් ලබා ගන්නේ කෙසේද?

ඔයාට පාවිච්චි කරන්න පුළුවන්:

  • sys.stdin- ගොනුවක් වැනි වස්තුවක් - sys.stdin.read()සියල්ල කියවීමට අමතන්න .
  • input(prompt)- එය ප්‍රතිදානය සඳහා විකල්ප විමසුමක් ලබා දෙන්න, එය stdin සිට පළමු නව රේඛාව දක්වා කියවනු ලැබේ. තවත් රේඛා ලබා ගැනීම සඳහා ඔබට මෙය නැවත නැවතත් කළ යුතුව ඇත, ආදානය අවසානයේ එය EOFError මතු කරයි. (බොහෝ විට ගොල්ෆ් ක්‍රීඩා කිරීම සඳහා එතරම් හොඳ නැත.) පයිතන් 2 හි මෙය වේ rawinput(prompt).
  • open(0).read()- පයිතන් 3 හි, බිල්ඩින් ශ්‍රිතය ගොනු විස්තර කරන්නන් openපිළිගනී (මෙහෙයුම් පද්ධති IO සම්පත් නියෝජනය කරන පූර්ණ සංඛ්‍යා), සහ 0 යනු විස්තර කරන්නා ය . එය ගොල්ෆ් වැනි වස්තුවක් නැවත ලබා දෙයි - බොහෝ විට ගොල්ෆ් ක්‍රීඩාව සඳහා ඔබේ හොඳම ඔට්ටුව. පයිතන් 2 හි මෙය වේ .stdinsys.stdinio.open
  • open('/dev/stdin').read()- සමාන open(0), පයිතන් 2 සහ 3 මත ක්‍රියා කරයි, නමුත් වින්ඩෝස් මත නොවේ (හෝ සිග්වින් පවා).
  • fileinput.input()- ලැයිස්තුගත කර ඇති සියලුම ලිපිගොනු වල රේඛා හරහා sys.argv[1:]ඉරේටරයක් ​​ලබා දෙයි, නැතහොත් ලබා නොදුනහොත් stdin. වැනි භාවිතා කරන්න ''.join(fileinput.input()).

දෙකම sysසහ fileinputපිළිවෙලින් ආනයනය කළ යුතුය.

sys.stdinපයිතන් 2 සහ 3, වින්ඩෝස්, යුනික්ස් සමඟ අනුකූල වන ඉක්මන් උදාහරණ

ඔබ කළ යුත්තේ readසිට sys.stdin: උදාහරණයක් ලෙස, ඔබ නල දත්ත 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පයිතන් 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පයිතන් 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පයිතන් 2 හි)

බිල්ඩින් ශ්‍රිතය inputසම්මත ආදානයේ සිට නව රේඛාවක් දක්වා කියවනු ලැබේ, එය ඉවත් කරනු ලැබේ (අනුපූරකව print, පෙරනිමියෙන් නව රේඛාවක් එක් කරයි.) මෙය සිදුවන්නේ එය EOF (ගොනුවේ අවසානය) ලබා ගන්නා තෙක්ය, එම අවස්ථාවේදී එය මතු EOFErrorවේ.

මේ අනුව, ඔබට stdin වෙතින් කියවීම inputසඳහා Python 3 (හෝ raw_inputPython 2) භාවිතා කළ හැකි ආකාරය මෙන්න - එබැවින් අපි stdindemo.py ලෙස හඳුන්වන පයිතන් මොඩියුලයක් සාදන්නෙමු:

$ 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අවසන්-of-ගොනුව චරිතය ලැබෙන, එය අප නොසලකා පසුව වැඩසටහනෙන් ඉවත් කරන EOFError, මතු කරයි.

ලිනක්ස් / යුනික්ස් මත අපට බළලාගෙන් පයිප්ප දැමිය හැකිය:

$ 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පයිතන් 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(අපි තවමත් stdout වෙත ලිඛිතව සඳහා 'W' අවශ්ය බව සඳහන් කර 2, සහ) Python 3.

මෙය ඔබේ පද්ධතියේ ක්‍රියාත්මක වන්නේ නම්, එය තවත් අක්ෂර රැවුල කපයි.

$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo

පයිතන් 2 හි io.openමෙයද සිදු කරයි, නමුත් ආනයනය සඳහා වැඩි ඉඩක් අවශ්‍ය වේ:

$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt 
foo
bar
baz

වෙනත් අදහස් හා පිළිතුරු ඇමතීම

එක් විවරණයක් ''.join(sys.stdin)ගොල්ෆ් ක්‍රීඩාව සඳහා යෝජනා කරන නමුත් එය ඇත්ත වශයෙන්ම sys.stdin.read () ට වඩා දිගු වේ - ප්ලස් පයිතන් මතකයේ අතිරේක ලැයිස්තුවක් නිර්මාණය කළ යුතුය ( str.joinලැයිස්තුවක් ලබා නොදෙන විට එය ක්‍රියා කරයි) - ඊට වෙනස්ව:

''.join(sys.stdin)
sys.stdin.read()

ඉහළම පිළිතුරෙන් ඇඟවෙන්නේ:

import fileinput

for line in fileinput.input():
    pass

නමුත්, sys.stdiniterator ප්‍රොටෝකෝලය ඇතුළුව ගොනු API ක්‍රියාත්මක කරන බැවින් එය මේ හා සමාන වේ:

import sys

for line in sys.stdin:
    pass

තවත් පිළිතුර වන්නේ මෙම යෝජනා කරමු. මතක තබා ගන්න ඔබ එය පරිවර්තකයෙකු තුළ කරන්නේ නම්, ඔබ කළ යුත්තේ Ctrl- dඔබ ලිනක්ස් හෝ මැක්හි නම්, හෝ Ctrl- zවින්ඩෝස් හි (පසුව Enter) ගොනුවේ අවසාන අක්‍ෂරය ක්‍රියාවලියට යැවීමට ය. එසේම, එම පිළිතුරෙන් ඇඟවෙන්නේ print(line)- එය '\n'අවසානයට එකතු කරන - print(line, end='')ඒ වෙනුවට භාවිතා කරන්න (පයිතන් 2 හි නම්, ඔබට අවශ්‍ය වනු ඇත from __future__ import print_function).

සඳහා සැබෑ භාවිත අවස්ථාව fileinputවන්නේ ලිපිගොනු මාලාවක් කියවීමයි.


103

අන් අය විසින් යෝජනා කරන ලද පිළිතුර:

for line in sys.stdin:
  print line

ඉතා සරල හා පයිතොනික් වේ, නමුත් ආදාන රේඛා මත නැවත යෙදීමට පෙර ස්ක්‍රිප්ට් EOF තෙක් බලා සිටින බව සැලකිල්ලට ගත යුතුය.

මෙයින් අදහස් කරන්නේ tail -f error_log | myscript.pyඅපේක්ෂිත පරිදි රේඛා සැකසෙන්නේ නැති බවයි.

එවැනි භාවිත නඩුවක් සඳහා නිවැරදි පිටපත වනුයේ:

while 1:
    try:
        line = sys.stdin.readline()
    except KeyboardInterrupt:
        break

    if not line:
        break

    print line

යාවත්කාලීන
කිරීම අදහස් වලින් පැහැදිලි වී ඇත්තේ පයිතන් 2 හි පමණක් බෆරින් සම්බන්ධ විය හැකි බැවින් මුද්‍රණ ඇමතුම නිකුත් කිරීමට පෙර බෆරය පිරවීම හෝ ඊඕඑෆ් එනතෙක් බලා සිටීමයි.


8
මෙම for line in sys.stdin:රටාව නැත EOF සඳහා රැඳී සිටින්න. නමුත් ඔබ ඉතා කුඩා ලිපිගොනු පරීක්ෂා කරන්නේ නම්, ප්‍රතිචාර බෆර් විය හැක. අතරමැදි ප්‍රති .ල කියවන බව බැලීමට තවත් දත්ත සමඟ පරීක්ෂා කරන්න.
mb.

පයිතන් 2.6.6 භාවිතා කරන විට ප්‍රවාහයකින් ආදානය ගන්නා විට, එන්ඩ් ඔෆ් ෆයිල් හෝ බෆරින් සඳහා මම බලා සිටිමි, නමුත් 3.1.3 සමඟ මම එසේ නොකරමි. සටහන print line3.1.3 හි අවදි නොවේ, නමුත් print(line)එසේ වේ.
ctrl-alt-delor

මගේ පයිතන් 2.7.5 “sys.stdin රේඛාව සඳහා”, EOF තෙක් අවහිර කිරීම හෝ යම් සාධාරණ දත්ත ප්‍රමාණයක් බෆර් කර ඇත. ධාරා සැකසුම් සඳහා හොඳයි. රේඛා සැකසුම් හෝ පරිශීලක ආදානය අනුව රේඛාව සඳහා හොඳ නැත.
ෂෝන්

2
මෙය libc හි tty හඳුනා ගැනීම හා සම්බන්ධ යැයි මම සැක කරමි, එබැවින් ඔබ එය අන්තර්ක්‍රියාකාරී කවචයක් මත හඳුනාගත් විට එය කිසිවක් හඳුනා නොගනී, අපේක්‍ෂාවෙන් ඉවත් නොකිරීම dev යනු ld_preload හරහා ෂිම් එකක් එන්නත් කරන බව මම විශ්වාස කරමි, එබැවින් is_atty සත්‍ය වේ (මම එය භාර දෙන්නේ කෙසේදැයි සැක කරන්න)
Mâtt Frman

8
E සීන්: වැරදියි . for line in sys.stdin:"EOF තෙක් අවහිර නොකරයි". ඒ නිසා එය Python 2, කියවීම සඳහා ඉදිරියට දෝෂ රේඛා පමා බව අනුරූප බෆරය පිරී තෙක්. එය EOF හා සම්බන්ධ නොවන බෆරින් ගැටළුවකි. ක්‍රියා කිරීමට, භාවිතා කරන්න for line in iter(sys.stdin.readline, ''):( io.open()සාමාන්‍ය ලිපිගොනු සඳහා භාවිතා කරන්න ). ඔබට එය පයිතන් 3 හි අවශ්‍ය නොවේ.
jfs

39

මෙය සම්මත ප්‍රතිදානය සම්මත ප්‍රතිදානයට ප්‍රතිරාවය කරයි:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()

31

භාවිතා කරන සියලුම ඇන්වර්ස් මත ගොඩනැඟීමෙන් sys.stdin, අවම වශයෙන් එක් තර්කයක් හෝ තිබේ නම්, තර්ක ගොනුවකින් කියවීම සඳහා ඔබට පහත සඳහන් දේ කළ හැකිය.

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

එවැනි බොහෝ GNU / යුනික්ස් වැඩසටහන් වැනි ඔබේ Python කේත රචනය වටේ සංචාරවල යෙදෙමින් කරන්න වනු ඇත cat, grepහා sed.


17

argparse පහසු විසඳුමකි

උදාහරණය පයිතන් අනුවාද 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

  හෝ වෙනුවට කෙටි echoවිසින් මෙහි සංගීත :

./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 -

ආදාන ගොනුව සම්පීඩනය කර ඇත්නම් කුමක් කළ යුතුද යන්න පිළිබඳ පිළිතුරක් මෙහි දැක්වේ: stackoverflow.com/a/33621549/778533 කෙනෙකුට ද කළ හැකි add_argument('--in'අතර පසුව ස්ක්‍රිප්ටයට නළය ගෙන --in -විධාන රේඛාවට එක් කරන්න . PS inයනු විචල්ය / ගුණාංග සඳහා ඉතා හොඳ නමක් නොවේ.
tommy.carstensen

inවිචල්‍යයකට නරක නමක් පමණක් නොවේ, එය නීති විරෝධී ය. වෙන් කර ඇති මූල පදය args.in.read()නිසා අවලංගු සින්ටැක්ස් දෝෂයක් මතු කරයි in. infileපයිතන් ආර්ග්පාර්ස් ඩොක්ස් වලට කැමති ලෙස සරලව නම් කළ හැකිය : docs.python.org/3/library/…
කෙන් කොල්ටන්

ඔබගේ ප්‍රතිපෝෂණයට ස්තූතියි @ tommy.carstensen, මම දැන් පිළිතුර වැඩි දියුණු කර ඇත්තෙමි. සුභ නත්තලක් සහ සුබ නව වසරක් වේවා ;-)
ඔලිබ්‍රේ

14

පහත දැක්වෙන කේත චිපය ඔබට උපකාරී වනු ඇත (එය සියලුම ස්ටීඩින් අවහිර කිරීම් EOFඑක නූලකට කියවනු ඇත ):

import sys
input_str = sys.stdin.read()
print input_str.split()

8

කිසිවෙකු මේ කඩුල්ල ගැන මෙතෙක් සඳහන් නොකිරීම ගැන මම පුදුම වෙමි:

python -c "import sys; set(map(sys.stdout.write,sys.stdin))"

python2 හි ඔබට set()ඇමතුම අතහැර දැමිය හැකිය , නමුත් එය දෙයාකාරයෙන්ම කියනු ඇත


1
readlinesඑම භේදය රේඛා වලට joinනැවත නැවත භාවිතා කරන්නේ ඇයි ? ඔබට ලිවිය හැකියprint(sys.stdin.read())
musiphil

මෙය අවශ්‍ය ප්‍රමාණයට වඩා වැඩි මතකයක් භාවිතා කරනු ඇත, මන්ද පයිතන්ට අමතර අරාවක් සෑදිය යුතු බැවිනි.
හැරී මොරෙනෝ

හොඳයි, ඇත්ත වශයෙන්ම නොවේ, මන්ද writeප්‍රතිලාභ None, සහ නියම කළ ප්‍රමාණය කිසි විටෙකත් 1 ( =len(set([None]))) ට වඩා වැඩි නොවනු ඇත
යූරි ගෝරන්

7

මේක උත්සාහ කරන්න:

import sys

print sys.stdin.read().upper()

එය සමඟ පරීක්ෂා කරන්න:

$ echo "Hello World" | python myFile.py

7

ඔබට stdin වෙතින් කියවිය හැකි අතර පසුව ආදාන "දත්ත" වෙත ගබඩා කළ හැකිය :

data = ""
for line in sys.stdin:
    data += line


data = sys.stdin.read()පුනරාවර්තී නූල් සංක්ෂිප්ත ගැටළුවකින් තොරව එකම දේ කළ හැකිය .
musiphil

6

සිට කියවන්න sys.stdin, නමුත් වින්ඩෝස් හි ද්විමය දත්ත කියවීමට , ඔබ වැඩිපුර සැලකිලිමත් විය යුතුය, මන්ද sys.stdinපෙළ මාදිලියේ විවෘත කර ඇති අතර ඒවා \r\nප්‍රතිස්ථාපනය කිරීමෙන් එය දූෂිත වනු ඇත \n.

විසඳුම වන්නේ වින්ඩෝස් + පයිතන් 2 අනාවරණය වුවහොත් සහ පයිතන් 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()

4

මම පහත දැක්වෙන ක්‍රමය භාවිතා කරමි, එය stdin වෙතින් නූලක් ලබා දෙයි (මම එය json විග්‍රහ කිරීම සඳහා භාවිතා කරමි). එය වින්ඩෝස් මත නල සහ විමසුමක් සමඟ ක්‍රියා කරයි (තවමත් ලිනක්ස් හි පරීක්ෂා කර නොමැත). විමසීමේදී, පේළි දෙකක බිඳීම් ආදානයේ අවසානය දක්වයි.

def get_from_stdin():

  lb = 0
  stdin = ''

  for line in sys.stdin:
    if line == "\n":
        lb += 1
        if lb == 2:
            break
    else:
        lb = 0
        stdin += line

  return stdin

3

විසඳුම සමඟ මට ඇති ගැටළුව

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)

තත්වය කෙසේ වෙතත් මෙම පිළිකුල්සහගත සැඟවීමට මම තරයේ නිර්දේශ කරමි.
tiktak

1
මෙම ක්‍රමය මඟින් වැඩසටහනේ අදාළතාවය බැරෑරුම් ලෙස සීමා කරයි: නිදසුනක් ලෙස, ඔබට මෙය පර්යන්තයෙන් අන්තර්ක්‍රියාකාරී ආදානය සඳහා භාවිතා කළ නොහැක, මන්ද ආදානය selectකැඳවූ විට කිසි විටෙකත් “සූදානම්” නොවනු ඇත ; මන්දගාමී මාධ්‍යයක (ජාල, සංයුක්ත තැටි, ටේප්, ආදිය) ගොනුවකට stdin සම්බන්ධ වී ඇත්නම් ඔබට ගැටළු වලටද මුහුණ දිය හැකිය. ඔබ කියා සිටියේ "ඔබ කිසිදු දත්තයක් stdin වෙත නොයවන්නේ නම් එය සදහටම අවහිර වනු ඇත." යනු ප්රශ්නයක් , නමුත් මම එය තියෙන්නේ කියන්නේ ලක්ෂණය . බොහෝ CLI වැඩසටහන් (උදා cat) මේ ආකාරයට ක්‍රියාත්මක වන අතර ඒවා අපේක්ෂා කෙරේ. ආදානයේ අවසානය හඳුනා ගැනීම සඳහා ඔබ රඳා පැවතිය යුතු එකම දෙය EOF ය.
musiphil

2

සොකට් වලට නල මාර්ගයෙන් කියවීම සඳහා මෙය ක්‍රියාත්මක කිරීමේදී මට යම් ගැටළු ඇති විය. සොකට් එක වසා දැමූ විට එය ක්‍රියාකාරී ලූපයක හිස් නූලක් නැවත ලබා දීමට පටන් ගත්තේය. එබැවින් මෙය මගේ විසඳුමයි (මම ලිනක්ස් වලින් පමණක් පරීක්‍ෂා කළ නමුත් එය අනෙක් සියලුම පද්ධතිවල ක්‍රියාත්මක වේ යැයි සිතමි)

import sys, os
sep=os.linesep

while sep == os.linesep:
    data = sys.stdin.readline()               
    sep = data[-len(os.linesep):]
    print '> "%s"' % data.strip()

එබැවින් ඔබ සොකට්ටුවකින් සවන් දීමට පටන් ගන්නේ නම් එය නිසියාකාරව ක්‍රියාත්මක වේ (උදා: කඩිනමින්):

while :; do nc -l 12345 | python test.py ; done

ඔබට එය ටෙල්නෙට් සමඟ ඇමතිය හැකිය, නැතහොත් බ්‍රව්සරයක් localhost වෙත යොමු කරන්න: 12345


1

මේ සම්බන්ධයෙන්:

for line in sys.stdin:

මම එය ඉතා විශාල ගොනුවක් සඳහා පයිතන් 2.7 (වෙනත් කෙනෙකුගේ යෝජනාවක් අනුගමනය කරමින්) අත්හදා බැලුවෙමි, මම එය නිර්දේශ නොකරමි, හරියටම ඉහත සඳහන් කළ හේතු නිසා (කිසිවක් දීර් long කාලයක් තිස්සේ සිදු නොවේ).

මම තරමක් වැඩි පයිතොනික් විසඳුමක් සමඟ අවසන් කළෙමි (එය විශාල ලිපිගොනු මත ක්‍රියා කරයි):

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

ගොනුවක් විවෘත කිරීම ප්‍රශ්නය අසන ආකාරයට stdin වෙතින් කියවීම නොවේ. -1
ආරොන් ශාලාව

මෙම අවස්ථාවේ දී මම sys.stdinවිධාන රේඛා විවාදයක් ලෙස පිටපතට යමි.
szeitlin

1
sys.stdinවිධාන රේඛා තර්කයක් ලෙස ස්ක්‍රිප්ටයට ඔබ යා හැක්කේ කෙසේද ? තර්ක යනු නූල් වන අතර ධාරාවන් ගොනු වැනි වස්තූන් වේ, ඒවා සමාන නොවේ.
ඩීෆේසර්

E ඩීෆේසර් එය භාවිතා කරන ආකාරය පෙන්වීමට සංස්කරණය කරන ලදි. තර්ක යනු නූල් ය, ඔව්, නමුත් මම කලින් සඳහන් කළ පයිතන් ඩොක්ස් සහ මා කලින් සඳහන් කළ පරිදි, sys.stdinගොනුවක් වැනි වස්තුවකි
szeitlin

1

සඳහා python, 3 බව වනු ඇත:

# Filename e.g. cat.py
import sys

for line in sys.stdin:
    print(line, end="")

මෙය මූලික වශයෙන් බළලුන්ගේ සරල ආකාරයකි (1), එය එක් එක් පේළියට පසුව නව රේඛාවක් එක් නොකරයි. ඔබට මෙය භාවිතා කළ හැකිය (ඔබ ගොනුව ක්‍රියාත්මක කළ හැකි chmod +x cat.pyලෙස සලකුණු කළ පසු :

echo Hello | ./cat.py

0

නැත os.read(0, x) stdin නියෝජනය කරන 0 සිට xbytes සඳහන් වන්නේ. මෙය නොවරදින කියවීමකි, sys.stdin.read () ට වඩා අඩු මට්ටමකි


0

-cවිධානය භාවිතා කරන විට , කියවීම වෙනුවට උපක්‍රමශීලී ක්‍රමයක් ලෙසstdin (සහ සමහර අවස්ථාවල වඩාත් නම්‍යශීලී) ඔබට ෂෙල් ස්ක්‍රිප්ට් විධානයක් මෙන්ම ඔබේ පයිතන් විධානයටත් යැවිය හැකිය $.

උදා

python3 -c "import sys; print(len(sys.argv[1].split('\n')))" "$(cat ~/.goldendict/history)"

මෙය ගෝල්ඩෙන්ඩික්ට් හි ඉතිහාස ගොනුවේ පේළි ගණන ගණනය කරනු ඇත.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.