How do I make python programs behave like proper unix tools?
I have a few Python scripts laying around, and I'm working on rewriting them. I have the same problem with all of them.
It's not obvious to me how to write the programs so that they behave like proper unix tools.
Because this
$ cat characters | progname
and this
$ progname characters
should produce the same output.
The closest thing I could find to that in Python was the fileinput library. Unfortunately, I don't really see how to rewrite my Python scripts, all of which look like this:
#!/usr/bin/env python
# coding=UTF-8
import sys, re
for file in sys.argv[1:]:
f = open(file)
fs = f.read()
regexnl = re.compile('[^sw.,?!:;-]')
rstuff = regexnl.sub('', fs)
f.close()
print rstuff
The fileinput library processes stdin if there is a stdin, and processes a file if there is a file. But it iterates over single lines.
import fileinput
for line in fileinput.input():
process(line)
I really don't get that. I guess if you're dealing with small files, or if you're not doing much to the files, this may seem obvious. But, for my purposes, this makes it much slower than simply opening the entire file and reading it into a string, as above.
Currently I run the script above like
$ pythonscript textfilename1 > textfilename2
But I want to be able to run it (and its brethren) in pipes, like
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
text-processing pipe python stdout stdin
add a comment |
I have a few Python scripts laying around, and I'm working on rewriting them. I have the same problem with all of them.
It's not obvious to me how to write the programs so that they behave like proper unix tools.
Because this
$ cat characters | progname
and this
$ progname characters
should produce the same output.
The closest thing I could find to that in Python was the fileinput library. Unfortunately, I don't really see how to rewrite my Python scripts, all of which look like this:
#!/usr/bin/env python
# coding=UTF-8
import sys, re
for file in sys.argv[1:]:
f = open(file)
fs = f.read()
regexnl = re.compile('[^sw.,?!:;-]')
rstuff = regexnl.sub('', fs)
f.close()
print rstuff
The fileinput library processes stdin if there is a stdin, and processes a file if there is a file. But it iterates over single lines.
import fileinput
for line in fileinput.input():
process(line)
I really don't get that. I guess if you're dealing with small files, or if you're not doing much to the files, this may seem obvious. But, for my purposes, this makes it much slower than simply opening the entire file and reading it into a string, as above.
Currently I run the script above like
$ pythonscript textfilename1 > textfilename2
But I want to be able to run it (and its brethren) in pipes, like
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
text-processing pipe python stdout stdin
5
See here: stackoverflow.com/questions/1744989/read-from-file-or-stdin
– Mat
Sep 4 '12 at 11:13
add a comment |
I have a few Python scripts laying around, and I'm working on rewriting them. I have the same problem with all of them.
It's not obvious to me how to write the programs so that they behave like proper unix tools.
Because this
$ cat characters | progname
and this
$ progname characters
should produce the same output.
The closest thing I could find to that in Python was the fileinput library. Unfortunately, I don't really see how to rewrite my Python scripts, all of which look like this:
#!/usr/bin/env python
# coding=UTF-8
import sys, re
for file in sys.argv[1:]:
f = open(file)
fs = f.read()
regexnl = re.compile('[^sw.,?!:;-]')
rstuff = regexnl.sub('', fs)
f.close()
print rstuff
The fileinput library processes stdin if there is a stdin, and processes a file if there is a file. But it iterates over single lines.
import fileinput
for line in fileinput.input():
process(line)
I really don't get that. I guess if you're dealing with small files, or if you're not doing much to the files, this may seem obvious. But, for my purposes, this makes it much slower than simply opening the entire file and reading it into a string, as above.
Currently I run the script above like
$ pythonscript textfilename1 > textfilename2
But I want to be able to run it (and its brethren) in pipes, like
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
text-processing pipe python stdout stdin
I have a few Python scripts laying around, and I'm working on rewriting them. I have the same problem with all of them.
It's not obvious to me how to write the programs so that they behave like proper unix tools.
Because this
$ cat characters | progname
and this
$ progname characters
should produce the same output.
The closest thing I could find to that in Python was the fileinput library. Unfortunately, I don't really see how to rewrite my Python scripts, all of which look like this:
#!/usr/bin/env python
# coding=UTF-8
import sys, re
for file in sys.argv[1:]:
f = open(file)
fs = f.read()
regexnl = re.compile('[^sw.,?!:;-]')
rstuff = regexnl.sub('', fs)
f.close()
print rstuff
The fileinput library processes stdin if there is a stdin, and processes a file if there is a file. But it iterates over single lines.
import fileinput
for line in fileinput.input():
process(line)
I really don't get that. I guess if you're dealing with small files, or if you're not doing much to the files, this may seem obvious. But, for my purposes, this makes it much slower than simply opening the entire file and reading it into a string, as above.
Currently I run the script above like
$ pythonscript textfilename1 > textfilename2
But I want to be able to run it (and its brethren) in pipes, like
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
text-processing pipe python stdout stdin
text-processing pipe python stdout stdin
edited Oct 4 '16 at 17:01
JJoao
7,1691928
7,1691928
asked Sep 4 '12 at 10:53
ixtmixilixixtmixilix
5,4861959101
5,4861959101
5
See here: stackoverflow.com/questions/1744989/read-from-file-or-stdin
– Mat
Sep 4 '12 at 11:13
add a comment |
5
See here: stackoverflow.com/questions/1744989/read-from-file-or-stdin
– Mat
Sep 4 '12 at 11:13
5
5
See here: stackoverflow.com/questions/1744989/read-from-file-or-stdin
– Mat
Sep 4 '12 at 11:13
See here: stackoverflow.com/questions/1744989/read-from-file-or-stdin
– Mat
Sep 4 '12 at 11:13
add a comment |
6 Answers
6
active
oldest
votes
Why not just
files = sys.argv[1:]
if not files:
files = ["/dev/stdin"]
for file in files:
f = open(file)
...
11
sys.stdin
should be used instead as it's more portable than hardcoded path to file.
– Piotr Dobrogost
Feb 3 '15 at 10:26
sys.stdin
should be used instead, as Piotr says
– smci
Nov 11 '15 at 4:27
Butsys.stdin
is a file, and it's already open, and must not be closed. Impossible to handle just like a file argument without jumping through hoops.
– alexis
Jan 11 at 14:14
@alexis Sure, if you want to closef
, or want to use a context manager, you need something more complex. See my new answer as an alternative.
– Mikel
Jan 12 at 5:17
add a comment |
Check if a filename is given as an argument, or else read from sys.stdin
.
Something like this:
if sys.argv[1]:
f = open(sys.argv[1])
else:
f = sys.stdin
It's similar to Mikel's answer except it uses the sys
module. I figure if they have it in there it must be for a reason...
What if two file names are specified on the command line?
– Mikel
Sep 4 '12 at 21:28
3
Oh absolutely! I didn't bother showing it because it was already shown in your answer. At some point you have to trust the user to decide what she needs. But feel free to edit if you believe this is best. My point is only to replace"open(/dev/stdin")
withsys.stdin
.
– rahmu
Sep 4 '12 at 21:40
1
you may want to checkif len(sys.argv)>1:
instead ofif sys.argv[1]:
otherwise you get an index out of range error
– Yibo Yang
Sep 21 '16 at 2:53
add a comment |
My preferred way of doing it turns out to be... (and this is taken from a nice little Linux blog called Harbinger's Hollow)
#!/usr/bin/env python
import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename:
string = open(args.filename).read()
elif not sys.stdin.isatty():
string = sys.stdin.read()
else:
parser.print_help()
The reason why I liked this best is that, as the blogger says, it just outputs a silly message if accidentally called without input. It also slots so nicely into all of my existing Python scripts that I have modified them all to include it.
3
Sometimes you do want to enter the input interactively from a tty; checkingisatty
and bailing out does not conform to the philosophy of Unix filters.
– musiphil
Sep 24 '13 at 7:58
Apart from theisatty
wart, this covers useful and important ground not found in the other answers, so it gets my upvote.
– tripleee
Sep 23 '15 at 5:53
add a comment |
files=sys.argv[1:]
for f in files or [sys.stdin]:
if isinstance(f, file):
txt = f.read()
else:
txt = open(f).read()
process(txt)
This is how I would have written it, if/dev/stdin
were unavailable on all my systems.
– Mikel
Jun 20 '18 at 16:12
add a comment |
I am using this solution and it works like a charm. Actually I am using in a script calle unaccent that lowercases and removes accents from a given string
argument = sys.argv[1:] if len(sys.argv) > 1 else sys.stdin.read()
I guess the firest time I saw this solution was here.
add a comment |
If your system doesn't have /dev/stdin
, or you want a more general solution, you could try something more complicated like:
class Stdin(object):
def __getattr__(self, attr):
return getattr(sys.stdin, attr)
def __enter__(self):
return self
def myopen(path):
if path == "-":
return Stdin()
return open(path)
for n in sys.argv[1:] or ["-"]:
with myopen(n) as f:
...
Why do you move the file pointer on exit? Bad idea. If input was redirected from a file, the next program will read it again. (And if stdin is a terminal, seek usually does nothing, right?) Just leave it alone.
– alexis
2 days ago
Yeah, done. I just thought it was cute to use-
multiple times. :)
– Mikel
2 days ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f47098%2fhow-do-i-make-python-programs-behave-like-proper-unix-tools%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
Why not just
files = sys.argv[1:]
if not files:
files = ["/dev/stdin"]
for file in files:
f = open(file)
...
11
sys.stdin
should be used instead as it's more portable than hardcoded path to file.
– Piotr Dobrogost
Feb 3 '15 at 10:26
sys.stdin
should be used instead, as Piotr says
– smci
Nov 11 '15 at 4:27
Butsys.stdin
is a file, and it's already open, and must not be closed. Impossible to handle just like a file argument without jumping through hoops.
– alexis
Jan 11 at 14:14
@alexis Sure, if you want to closef
, or want to use a context manager, you need something more complex. See my new answer as an alternative.
– Mikel
Jan 12 at 5:17
add a comment |
Why not just
files = sys.argv[1:]
if not files:
files = ["/dev/stdin"]
for file in files:
f = open(file)
...
11
sys.stdin
should be used instead as it's more portable than hardcoded path to file.
– Piotr Dobrogost
Feb 3 '15 at 10:26
sys.stdin
should be used instead, as Piotr says
– smci
Nov 11 '15 at 4:27
Butsys.stdin
is a file, and it's already open, and must not be closed. Impossible to handle just like a file argument without jumping through hoops.
– alexis
Jan 11 at 14:14
@alexis Sure, if you want to closef
, or want to use a context manager, you need something more complex. See my new answer as an alternative.
– Mikel
Jan 12 at 5:17
add a comment |
Why not just
files = sys.argv[1:]
if not files:
files = ["/dev/stdin"]
for file in files:
f = open(file)
...
Why not just
files = sys.argv[1:]
if not files:
files = ["/dev/stdin"]
for file in files:
f = open(file)
...
answered Sep 4 '12 at 13:37
MikelMikel
39.1k1099125
39.1k1099125
11
sys.stdin
should be used instead as it's more portable than hardcoded path to file.
– Piotr Dobrogost
Feb 3 '15 at 10:26
sys.stdin
should be used instead, as Piotr says
– smci
Nov 11 '15 at 4:27
Butsys.stdin
is a file, and it's already open, and must not be closed. Impossible to handle just like a file argument without jumping through hoops.
– alexis
Jan 11 at 14:14
@alexis Sure, if you want to closef
, or want to use a context manager, you need something more complex. See my new answer as an alternative.
– Mikel
Jan 12 at 5:17
add a comment |
11
sys.stdin
should be used instead as it's more portable than hardcoded path to file.
– Piotr Dobrogost
Feb 3 '15 at 10:26
sys.stdin
should be used instead, as Piotr says
– smci
Nov 11 '15 at 4:27
Butsys.stdin
is a file, and it's already open, and must not be closed. Impossible to handle just like a file argument without jumping through hoops.
– alexis
Jan 11 at 14:14
@alexis Sure, if you want to closef
, or want to use a context manager, you need something more complex. See my new answer as an alternative.
– Mikel
Jan 12 at 5:17
11
11
sys.stdin
should be used instead as it's more portable than hardcoded path to file.– Piotr Dobrogost
Feb 3 '15 at 10:26
sys.stdin
should be used instead as it's more portable than hardcoded path to file.– Piotr Dobrogost
Feb 3 '15 at 10:26
sys.stdin
should be used instead, as Piotr says– smci
Nov 11 '15 at 4:27
sys.stdin
should be used instead, as Piotr says– smci
Nov 11 '15 at 4:27
But
sys.stdin
is a file, and it's already open, and must not be closed. Impossible to handle just like a file argument without jumping through hoops.– alexis
Jan 11 at 14:14
But
sys.stdin
is a file, and it's already open, and must not be closed. Impossible to handle just like a file argument without jumping through hoops.– alexis
Jan 11 at 14:14
@alexis Sure, if you want to close
f
, or want to use a context manager, you need something more complex. See my new answer as an alternative.– Mikel
Jan 12 at 5:17
@alexis Sure, if you want to close
f
, or want to use a context manager, you need something more complex. See my new answer as an alternative.– Mikel
Jan 12 at 5:17
add a comment |
Check if a filename is given as an argument, or else read from sys.stdin
.
Something like this:
if sys.argv[1]:
f = open(sys.argv[1])
else:
f = sys.stdin
It's similar to Mikel's answer except it uses the sys
module. I figure if they have it in there it must be for a reason...
What if two file names are specified on the command line?
– Mikel
Sep 4 '12 at 21:28
3
Oh absolutely! I didn't bother showing it because it was already shown in your answer. At some point you have to trust the user to decide what she needs. But feel free to edit if you believe this is best. My point is only to replace"open(/dev/stdin")
withsys.stdin
.
– rahmu
Sep 4 '12 at 21:40
1
you may want to checkif len(sys.argv)>1:
instead ofif sys.argv[1]:
otherwise you get an index out of range error
– Yibo Yang
Sep 21 '16 at 2:53
add a comment |
Check if a filename is given as an argument, or else read from sys.stdin
.
Something like this:
if sys.argv[1]:
f = open(sys.argv[1])
else:
f = sys.stdin
It's similar to Mikel's answer except it uses the sys
module. I figure if they have it in there it must be for a reason...
What if two file names are specified on the command line?
– Mikel
Sep 4 '12 at 21:28
3
Oh absolutely! I didn't bother showing it because it was already shown in your answer. At some point you have to trust the user to decide what she needs. But feel free to edit if you believe this is best. My point is only to replace"open(/dev/stdin")
withsys.stdin
.
– rahmu
Sep 4 '12 at 21:40
1
you may want to checkif len(sys.argv)>1:
instead ofif sys.argv[1]:
otherwise you get an index out of range error
– Yibo Yang
Sep 21 '16 at 2:53
add a comment |
Check if a filename is given as an argument, or else read from sys.stdin
.
Something like this:
if sys.argv[1]:
f = open(sys.argv[1])
else:
f = sys.stdin
It's similar to Mikel's answer except it uses the sys
module. I figure if they have it in there it must be for a reason...
Check if a filename is given as an argument, or else read from sys.stdin
.
Something like this:
if sys.argv[1]:
f = open(sys.argv[1])
else:
f = sys.stdin
It's similar to Mikel's answer except it uses the sys
module. I figure if they have it in there it must be for a reason...
answered Sep 4 '12 at 15:16
rahmurahmu
10.3k1969110
10.3k1969110
What if two file names are specified on the command line?
– Mikel
Sep 4 '12 at 21:28
3
Oh absolutely! I didn't bother showing it because it was already shown in your answer. At some point you have to trust the user to decide what she needs. But feel free to edit if you believe this is best. My point is only to replace"open(/dev/stdin")
withsys.stdin
.
– rahmu
Sep 4 '12 at 21:40
1
you may want to checkif len(sys.argv)>1:
instead ofif sys.argv[1]:
otherwise you get an index out of range error
– Yibo Yang
Sep 21 '16 at 2:53
add a comment |
What if two file names are specified on the command line?
– Mikel
Sep 4 '12 at 21:28
3
Oh absolutely! I didn't bother showing it because it was already shown in your answer. At some point you have to trust the user to decide what she needs. But feel free to edit if you believe this is best. My point is only to replace"open(/dev/stdin")
withsys.stdin
.
– rahmu
Sep 4 '12 at 21:40
1
you may want to checkif len(sys.argv)>1:
instead ofif sys.argv[1]:
otherwise you get an index out of range error
– Yibo Yang
Sep 21 '16 at 2:53
What if two file names are specified on the command line?
– Mikel
Sep 4 '12 at 21:28
What if two file names are specified on the command line?
– Mikel
Sep 4 '12 at 21:28
3
3
Oh absolutely! I didn't bother showing it because it was already shown in your answer. At some point you have to trust the user to decide what she needs. But feel free to edit if you believe this is best. My point is only to replace
"open(/dev/stdin")
with sys.stdin
.– rahmu
Sep 4 '12 at 21:40
Oh absolutely! I didn't bother showing it because it was already shown in your answer. At some point you have to trust the user to decide what she needs. But feel free to edit if you believe this is best. My point is only to replace
"open(/dev/stdin")
with sys.stdin
.– rahmu
Sep 4 '12 at 21:40
1
1
you may want to check
if len(sys.argv)>1:
instead of if sys.argv[1]:
otherwise you get an index out of range error– Yibo Yang
Sep 21 '16 at 2:53
you may want to check
if len(sys.argv)>1:
instead of if sys.argv[1]:
otherwise you get an index out of range error– Yibo Yang
Sep 21 '16 at 2:53
add a comment |
My preferred way of doing it turns out to be... (and this is taken from a nice little Linux blog called Harbinger's Hollow)
#!/usr/bin/env python
import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename:
string = open(args.filename).read()
elif not sys.stdin.isatty():
string = sys.stdin.read()
else:
parser.print_help()
The reason why I liked this best is that, as the blogger says, it just outputs a silly message if accidentally called without input. It also slots so nicely into all of my existing Python scripts that I have modified them all to include it.
3
Sometimes you do want to enter the input interactively from a tty; checkingisatty
and bailing out does not conform to the philosophy of Unix filters.
– musiphil
Sep 24 '13 at 7:58
Apart from theisatty
wart, this covers useful and important ground not found in the other answers, so it gets my upvote.
– tripleee
Sep 23 '15 at 5:53
add a comment |
My preferred way of doing it turns out to be... (and this is taken from a nice little Linux blog called Harbinger's Hollow)
#!/usr/bin/env python
import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename:
string = open(args.filename).read()
elif not sys.stdin.isatty():
string = sys.stdin.read()
else:
parser.print_help()
The reason why I liked this best is that, as the blogger says, it just outputs a silly message if accidentally called without input. It also slots so nicely into all of my existing Python scripts that I have modified them all to include it.
3
Sometimes you do want to enter the input interactively from a tty; checkingisatty
and bailing out does not conform to the philosophy of Unix filters.
– musiphil
Sep 24 '13 at 7:58
Apart from theisatty
wart, this covers useful and important ground not found in the other answers, so it gets my upvote.
– tripleee
Sep 23 '15 at 5:53
add a comment |
My preferred way of doing it turns out to be... (and this is taken from a nice little Linux blog called Harbinger's Hollow)
#!/usr/bin/env python
import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename:
string = open(args.filename).read()
elif not sys.stdin.isatty():
string = sys.stdin.read()
else:
parser.print_help()
The reason why I liked this best is that, as the blogger says, it just outputs a silly message if accidentally called without input. It also slots so nicely into all of my existing Python scripts that I have modified them all to include it.
My preferred way of doing it turns out to be... (and this is taken from a nice little Linux blog called Harbinger's Hollow)
#!/usr/bin/env python
import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument('filename', nargs='?')
args = parser.parse_args()
if args.filename:
string = open(args.filename).read()
elif not sys.stdin.isatty():
string = sys.stdin.read()
else:
parser.print_help()
The reason why I liked this best is that, as the blogger says, it just outputs a silly message if accidentally called without input. It also slots so nicely into all of my existing Python scripts that I have modified them all to include it.
answered Sep 8 '12 at 12:12
ixtmixilixixtmixilix
5,4861959101
5,4861959101
3
Sometimes you do want to enter the input interactively from a tty; checkingisatty
and bailing out does not conform to the philosophy of Unix filters.
– musiphil
Sep 24 '13 at 7:58
Apart from theisatty
wart, this covers useful and important ground not found in the other answers, so it gets my upvote.
– tripleee
Sep 23 '15 at 5:53
add a comment |
3
Sometimes you do want to enter the input interactively from a tty; checkingisatty
and bailing out does not conform to the philosophy of Unix filters.
– musiphil
Sep 24 '13 at 7:58
Apart from theisatty
wart, this covers useful and important ground not found in the other answers, so it gets my upvote.
– tripleee
Sep 23 '15 at 5:53
3
3
Sometimes you do want to enter the input interactively from a tty; checking
isatty
and bailing out does not conform to the philosophy of Unix filters.– musiphil
Sep 24 '13 at 7:58
Sometimes you do want to enter the input interactively from a tty; checking
isatty
and bailing out does not conform to the philosophy of Unix filters.– musiphil
Sep 24 '13 at 7:58
Apart from the
isatty
wart, this covers useful and important ground not found in the other answers, so it gets my upvote.– tripleee
Sep 23 '15 at 5:53
Apart from the
isatty
wart, this covers useful and important ground not found in the other answers, so it gets my upvote.– tripleee
Sep 23 '15 at 5:53
add a comment |
files=sys.argv[1:]
for f in files or [sys.stdin]:
if isinstance(f, file):
txt = f.read()
else:
txt = open(f).read()
process(txt)
This is how I would have written it, if/dev/stdin
were unavailable on all my systems.
– Mikel
Jun 20 '18 at 16:12
add a comment |
files=sys.argv[1:]
for f in files or [sys.stdin]:
if isinstance(f, file):
txt = f.read()
else:
txt = open(f).read()
process(txt)
This is how I would have written it, if/dev/stdin
were unavailable on all my systems.
– Mikel
Jun 20 '18 at 16:12
add a comment |
files=sys.argv[1:]
for f in files or [sys.stdin]:
if isinstance(f, file):
txt = f.read()
else:
txt = open(f).read()
process(txt)
files=sys.argv[1:]
for f in files or [sys.stdin]:
if isinstance(f, file):
txt = f.read()
else:
txt = open(f).read()
process(txt)
edited Jun 20 '18 at 16:11
Mikel
39.1k1099125
39.1k1099125
answered Dec 12 '16 at 17:15
JJoaoJJoao
7,1691928
7,1691928
This is how I would have written it, if/dev/stdin
were unavailable on all my systems.
– Mikel
Jun 20 '18 at 16:12
add a comment |
This is how I would have written it, if/dev/stdin
were unavailable on all my systems.
– Mikel
Jun 20 '18 at 16:12
This is how I would have written it, if
/dev/stdin
were unavailable on all my systems.– Mikel
Jun 20 '18 at 16:12
This is how I would have written it, if
/dev/stdin
were unavailable on all my systems.– Mikel
Jun 20 '18 at 16:12
add a comment |
I am using this solution and it works like a charm. Actually I am using in a script calle unaccent that lowercases and removes accents from a given string
argument = sys.argv[1:] if len(sys.argv) > 1 else sys.stdin.read()
I guess the firest time I saw this solution was here.
add a comment |
I am using this solution and it works like a charm. Actually I am using in a script calle unaccent that lowercases and removes accents from a given string
argument = sys.argv[1:] if len(sys.argv) > 1 else sys.stdin.read()
I guess the firest time I saw this solution was here.
add a comment |
I am using this solution and it works like a charm. Actually I am using in a script calle unaccent that lowercases and removes accents from a given string
argument = sys.argv[1:] if len(sys.argv) > 1 else sys.stdin.read()
I guess the firest time I saw this solution was here.
I am using this solution and it works like a charm. Actually I am using in a script calle unaccent that lowercases and removes accents from a given string
argument = sys.argv[1:] if len(sys.argv) > 1 else sys.stdin.read()
I guess the firest time I saw this solution was here.
edited Jun 2 '18 at 10:24
answered Jun 2 '18 at 10:01
SergioAraujoSergioAraujo
1594
1594
add a comment |
add a comment |
If your system doesn't have /dev/stdin
, or you want a more general solution, you could try something more complicated like:
class Stdin(object):
def __getattr__(self, attr):
return getattr(sys.stdin, attr)
def __enter__(self):
return self
def myopen(path):
if path == "-":
return Stdin()
return open(path)
for n in sys.argv[1:] or ["-"]:
with myopen(n) as f:
...
Why do you move the file pointer on exit? Bad idea. If input was redirected from a file, the next program will read it again. (And if stdin is a terminal, seek usually does nothing, right?) Just leave it alone.
– alexis
2 days ago
Yeah, done. I just thought it was cute to use-
multiple times. :)
– Mikel
2 days ago
add a comment |
If your system doesn't have /dev/stdin
, or you want a more general solution, you could try something more complicated like:
class Stdin(object):
def __getattr__(self, attr):
return getattr(sys.stdin, attr)
def __enter__(self):
return self
def myopen(path):
if path == "-":
return Stdin()
return open(path)
for n in sys.argv[1:] or ["-"]:
with myopen(n) as f:
...
Why do you move the file pointer on exit? Bad idea. If input was redirected from a file, the next program will read it again. (And if stdin is a terminal, seek usually does nothing, right?) Just leave it alone.
– alexis
2 days ago
Yeah, done. I just thought it was cute to use-
multiple times. :)
– Mikel
2 days ago
add a comment |
If your system doesn't have /dev/stdin
, or you want a more general solution, you could try something more complicated like:
class Stdin(object):
def __getattr__(self, attr):
return getattr(sys.stdin, attr)
def __enter__(self):
return self
def myopen(path):
if path == "-":
return Stdin()
return open(path)
for n in sys.argv[1:] or ["-"]:
with myopen(n) as f:
...
If your system doesn't have /dev/stdin
, or you want a more general solution, you could try something more complicated like:
class Stdin(object):
def __getattr__(self, attr):
return getattr(sys.stdin, attr)
def __enter__(self):
return self
def myopen(path):
if path == "-":
return Stdin()
return open(path)
for n in sys.argv[1:] or ["-"]:
with myopen(n) as f:
...
edited 2 days ago
answered Jan 12 at 5:16
MikelMikel
39.1k1099125
39.1k1099125
Why do you move the file pointer on exit? Bad idea. If input was redirected from a file, the next program will read it again. (And if stdin is a terminal, seek usually does nothing, right?) Just leave it alone.
– alexis
2 days ago
Yeah, done. I just thought it was cute to use-
multiple times. :)
– Mikel
2 days ago
add a comment |
Why do you move the file pointer on exit? Bad idea. If input was redirected from a file, the next program will read it again. (And if stdin is a terminal, seek usually does nothing, right?) Just leave it alone.
– alexis
2 days ago
Yeah, done. I just thought it was cute to use-
multiple times. :)
– Mikel
2 days ago
Why do you move the file pointer on exit? Bad idea. If input was redirected from a file, the next program will read it again. (And if stdin is a terminal, seek usually does nothing, right?) Just leave it alone.
– alexis
2 days ago
Why do you move the file pointer on exit? Bad idea. If input was redirected from a file, the next program will read it again. (And if stdin is a terminal, seek usually does nothing, right?) Just leave it alone.
– alexis
2 days ago
Yeah, done. I just thought it was cute to use
-
multiple times. :)– Mikel
2 days ago
Yeah, done. I just thought it was cute to use
-
multiple times. :)– Mikel
2 days ago
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f47098%2fhow-do-i-make-python-programs-behave-like-proper-unix-tools%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
5
See here: stackoverflow.com/questions/1744989/read-from-file-or-stdin
– Mat
Sep 4 '12 at 11:13