Voglio scrivere un programma che legge stdin (senza buffer) e scrive stdout (senza buffer) eseguendo alcune trasformazioni di tipo char-by-char. Per fare un esempio, diciamo che voglio rimuovere tutti i caratteri x
dallo stdin.Come scrivere un filtro unix in python?
risposta
Non so esattamente che cosa si intende per tamponata in questo contesto, ma è abbastanza semplice da fare che cosa state chiedendo ...
so_gen.py (generando un flusso costante che possiamo guardare) :
import time
import sys
while True:
for char in 'abcdefx':
sys.stdout.write(char)
sys.stdout.flush()
time.sleep(0.1)
so_filter.py (fare ciò che si chiede):
import sys
while True:
char = sys.stdin.read(1)
if not char:
break
if char != 'x':
sys.stdout.write(char)
sys.stdout.flush()
provare a eseguire python so_gen.py | python so_filter.py
per vedere cosa fa.
Leggere da sys.stdin
e scrivere su sys.stdout
(o utilizzare print
). Il tuo programma di esempio:
import sys
for line in sys.stdin:
print line.replace("x", ""),
Non esiste un modo standard per fare stdin unbuffered, e non si vuole questo. Lascia che sia il buffer del sistema operativo.
Ha detto "senza buffer" ma non sono sicuro che importi davvero. –
Ho modificato la mia risposta come hai commentato. –
È possibile utilizzare lo fileinput
class, che consente di elaborare gli input come farebbe l'operatore Diamante Perl. Dalla documentazione:
import fileinput
for line in fileinput.input():
process(line)
processo in cui fa qualcosa di simile print line.replace('x','')
.
È possibile seguire this StackOverflow question per come annullare la stdout. Oppure puoi chiamare lo sys.stdout.flush()
dopo ogni print
.
Ah! Questo rende tutto il lavoro extra che stavo facendo perché ho perso Perl per nulla! Ho bisogno di passare attraverso la libreria standard Python molto da vicino. –
Utilizzare l'opzione -u per l'interprete python per rendere tutte le letture e le scritture senza buffer. Simile all'impostazione di $| = true;
in Perl. Quindi procedere come si farebbe, leggendo una riga modificandola e quindi stampandola. sys.stdout.flush() non richiesto.
#!/path/to/python -u
import sys
for line in sys.stdin:
process_line(line)
Non funziona qui ... –
vincitore per la scrittura di 'if not char: break' – flybywire
@flybywire: la sua risposta lo ha richiesto, nessun'altra risposta ha ... –