2009-10-19 687 views
9

Quiero escribir un programa que lee la entrada estándar (sin búfer) y escribe la salida estándar (sin búfer) haciendo algunas triviales transformación char-por-char. Por el bien del ejemplo digamos que quiero eliminar todos los caracteres x de stdin.¿Cómo escribo un filtro de Unix en Python?

Respuesta

7

No sé exactamente lo que quiere decir con buffer en este contexto, pero es muy simple de hacer lo que están pidiendo ...

so_gen.py (generando una corriente constante que podemos ver) :

import time 
import sys 
while True: 
    for char in 'abcdefx': 
     sys.stdout.write(char) 
     sys.stdout.flush() 
     time.sleep(0.1) 

so_filter.py (haciendo lo que pide):

import sys 
while True: 
    char = sys.stdin.read(1) 
    if not char: 
     break 
    if char != 'x': 
     sys.stdout.write(char) 
     sys.stdout.flush() 

intente ejecutar python so_gen.py | python so_filter.py para ver lo que hace.

+1

ganador para escribir 'if not char: break' – flybywire

+1

@flybywire: Su respuesta lo necesitaba, ninguna otra respuesta lo hizo ... –

13

Lea de sys.stdin y escriba en sys.stdout (o use print). Su programa de ejemplo:

import sys 

for line in sys.stdin: 
    print line.replace("x", ""), 

No hay una forma estándar para hacer la entrada estándar sin búfer, y usted no quiere eso. Deje que el SO lo proteja.

+2

Él dijo "unbuffered" pero no estoy seguro de que realmente importe. –

+0

Edité mi respuesta como lo comentó. –

9

Puede utilizar el fileinput class, que le permite procesar insumos como el operador de diamantes Perl haría. A partir de los documentos:

import fileinput 
for line in fileinput.input(): 
    process(line) 

proceso en el que hace algo como print line.replace('x','').

Puede seguir this StackOverflow question de cómo retirar del búfer salida estándar. O simplemente puede llamar al sys.stdout.flush() después de cada print.

+0

¡Ah! ¡Esto hace todo el trabajo extra que estaba haciendo porque extrañaba a Perl por nada! Necesito examinar muy de cerca la biblioteca estándar de Python. –

2

Utilice el interruptor -u para el intérprete de Python para hacer todas las lecturas y escrituras sin búfer. Similar al ajuste $| = true; en Perl. Luego proceda como lo haría, leyendo una línea modificándola y luego imprimiéndola. sys.stdout.flush() no requerido.

#!/path/to/python -u 

import sys 

for line in sys.stdin: 
    process_line(line) 
+0

No funciona aquí ... –

Cuestiones relacionadas