0

I have following issue. I would like to read input from file (e.g. example.txt) to my Python script (e.g. script.py). Right now, I've implemented following lines of code:

import sys
with open(sys.argv[1], 'r') as f:
    contents = f.read()

And, when I want to read file to this script, I just need to type following line in CMD:

python script.py example.txt

And of course, it works properly. File example.txt is read by script.py, it can be checked by adding simple print(contents) line to script.py.

The problem is, I have to run this code in CMD just like that:

script.py < example.txt

So, the question is, how can I achieve that? I suppose, it depends on the OS. On my Windows 10, I'm getting an error:

Traceback (most recent call last):
File "script.py", line 2, in <module>
with open(sys.argv[1], 'r') as f:
IndexError: list index out of range

I'm not asking for solution (but it would be nice), but I just want to know where should I'm looking for a solution.

wujotx
  • 5
  • 2

1 Answers1

1

script.py < example.txt sends the file contents to stdin which can be accessed via sys.stdin. The following works:

import sys

# First try supporting commands formatted like: script.py example.txt
if len(sys.argv) > 1:
    with open(sys.argv[1]) as f:
        contents = f.read()
# Now try supporting: script.py < example.txt
elif sys.stdin:
    contents = ''.join(sys.stdin)
# If both methods failed, throw a user friendly error
else:
    raise Exception('Please supply a file')

print(contents)

But in good old Python fashion, there is a built-in library that can make our life very easy. The library is fileinput, and it will automatically support both methods of reading input that you mentioned:

import fileinput
contents = fileinput.input()
print( ''.join(contents) )

And that works regardless of if you do script.py example.txt or script.py < example.txt or cat example.txt | script.py and you can even do script.py example1.txt example2.txt example3.txt and you will receive the file contents of the different files combined together.

hostingutilities.com
  • 8,894
  • 3
  • 41
  • 51
  • Well, both methods seems to be working, only if I'm typing in CMD something like that: `python script.py < example.txt`. I mean, now I have "<" operator but I'm obligated to write "python" before. When writing just `script.py < example.txt`, I'm getting sth like that in console `[main 2021-05-20T16:52:13.375Z] update#setState idle`, also my script is being opened in VS Code (it's on Windows 10). I tried it also in online linux terminal, and I'm getting this: `bash: script.py: command not found`. So, is there any way to avoid writing "python" before other lines, or it is just mandatory? – wujotx May 20 '21 at 16:54
  • This might help you out https://stackoverflow.com/questions/37828739/run-python-program-without-python-in-windows#37828872 For Linux you need to add a shebang at the top of your script, see https://stackoverflow.com/questions/4993621/how-to-run-python-script-without-typing-python – hostingutilities.com May 21 '21 at 02:23
  • Thank You very much, everything is working properly right now. Best regards! – wujotx May 22 '21 at 18:13