I want to write a program that reads stdin (unbuffered) and writes stdout (unbuffered) doing some trivial char-by-char transformation. For the sake of the example let's say I want to remove all chars x from stdin.
4 Answers
You can use the fileinput class, which lets you process inputs like the Perl diamond operator would. From the docs:
import fileinput
for line in fileinput.input():
process(line)
where process does something like print line.replace('x','').
You can follow this StackOverflow question for how to unbuffer stdout. Or you can just call sys.stdout.flush() after each print.
2 Comments
fileinput module is made exactly for this use case.Read from sys.stdin and write to sys.stdout (or use print). Your example program:
import sys
for line in sys.stdin:
print line.replace("x", ""),
There isn't a standard way to make stdin unbuffered, and you don't want that. Let the OS buffer it.
1 Comment
I don't know exactly what you mean by buffered in this context, but it is pretty simple to do what you are asking...
so_gen.py (generating a constant stream that we can watch):
import time
import sys
while True:
for char in 'abcdefx':
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(0.1)
so_filter.py (doing what you ask):
import sys
while True:
char = sys.stdin.read(1)
if not char:
break
if char != 'x':
sys.stdout.write(char)
sys.stdout.flush()
Try running python so_gen.py | python so_filter.py to see what it does.
1 Comment
if not char: breakUse the -u switch for the python interpreter to make all reads and writes unbuffered. Similar to setting $| = true; in Perl. Then proceed as you would, reading a line modifying it and then printing it. sys.stdout.flush() not required.
#!/path/to/python -u
import sys
for line in sys.stdin:
process_line(line)