Tengo algunos scripts de Python por ahí, y estoy trabajando en reescribirlos. Tengo el mismo problema con todos ellos.
No es obvio para mí cómo escribir los programas para que se comporten como herramientas Unix adecuadas.
Porque esto
$ cat characters | progname
y esto
$ progname characters
debería producir la misma salida.
Lo más parecido que pude encontrar a eso en Python fue la biblioteca de entrada de archivos. Desafortunadamente, realmente no veo cómo reescribir mis scripts de Python, todos los cuales se ven así:
#!/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('[^\s\w.,?!:;-]')
rstuff = regexnl.sub('', fs)
f.close()
print rstuff
La biblioteca de entrada de archivos procesa stdin si hay un stdin, y procesa un archivo si hay un archivo. Pero itera sobre líneas simples.
import fileinput
for line in fileinput.input():
process(line)
Realmente no entiendo eso. Supongo que si se trata de archivos pequeños, o si no está haciendo mucho a los archivos, esto puede parecer obvio. Pero, para mis propósitos, esto lo hace mucho más lento que simplemente abrir todo el archivo y leerlo en una cadena, como se indicó anteriormente.
Actualmente ejecuto el script anterior como
$ pythonscript textfilename1 > textfilename2
Pero quiero poder ejecutarlo (y sus hermanos) en tuberías, como
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
Respuestas:
¿Por qué no solo
fuente
sys.stdin
debe usarse en su lugar, ya que es más portátil que la ruta codificada al archivo.sys.stdin
debería usarse en su lugar, como dice Piotrsys.stdin
es un archivo, y ya está abierto, y no debe cerrarse. Imposible de manejar como un argumento de archivo sin saltar a través de aros.f
o usar un administrador de contexto, necesita algo más complejo. Vea mi nueva respuesta como alternativa.Compruebe si se proporciona un nombre de archivo como argumento, o si no se lee
sys.stdin
.Algo como esto:
Es similar a la respuesta de Mikel, excepto que usa el
sys
módulo. Me imagino que si lo tienen allí debe ser por una razón ...fuente
"open(/dev/stdin")
consys.stdin
.if len(sys.argv)>1:
lugar de loif sys.argv[1]:
contrario obtendrá un error de índice fuera de rangoMi forma preferida de hacerlo resulta ser ... (y esto está tomado de un pequeño y lindo blog de Linux llamado Harbinger's Hollow )
La razón por la que me gustó más esto es que, como dice el blogger, solo emite un mensaje tonto si se llama accidentalmente sin entrada. También se integra tan bien en todos mis scripts de Python existentes que los modifiqué para incluirlos.
fuente
isatty
y el rescate no se ajusta a la filosofía de los filtros Unix.isatty
verruga, esto cubre un terreno útil e importante que no se encuentra en las otras respuestas, por lo que recibe mi voto positivo.fuente
/dev/stdin
no estuviera disponible en todos mis sistemas.Estoy usando esta solución y funciona de maravilla. En realidad estoy usando una secuencia de comandos que no está en acento que en minúsculas y elimina los acentos de una cadena dada
Creo que el mejor momento en que vi esta solución fue aquí .
fuente
Si su sistema no tiene
/dev/stdin
, o si desea una solución más general, puede intentar algo más complicado como:fuente
-
varias veces. :)