Quiero redirigir la impresión a un archivo .txt usando python. Tengo un bucle 'for', que 'imprimirá' la salida de cada uno de mis archivos .bam mientras quiero redirigir TODAS estas salidas a un archivo. Entonces traté de poner
f = open('output.txt','w'); sys.stdout = f
Al principio de mi guión. Sin embargo, no obtengo nada en el archivo .txt. Mi guión es:
#!/usr/bin/python
import os,sys
import subprocess
import glob
from os import path
f = open('output.txt','w')
sys.stdout = f
path= '/home/xug/nearline/bamfiles'
bamfiles = glob.glob(path + '/*.bam')
for bamfile in bamfiles:
filename = bamfile.split('/')[-1]
print 'Filename:', filename
samtoolsin = subprocess.Popen(["/share/bin/samtools/samtools","view",bamfile],
stdout=subprocess.PIPE,bufsize=1)
linelist= samtoolsin.stdout.readlines()
print 'Readlines finished!'
........print....
........print....
¿Entonces, cuál es el problema? ¿De alguna otra manera además de este sys.stdout?
Necesito que mi resultado se vea así:
Filename: ERR001268.bam
Readlines finished!
Mean: 233
SD: 10
Interval is: (213, 252)
python
file-writing
LookIntoEast
fuente
fuente
f.write(data)
?f.write(line)
- inserta un salto de línea al final.f.write(line)
no agrega un salto de línea a los datos.f.write(line+'\n')
Sin embargo, siempre podría ...Respuestas:
La forma más obvia de hacer esto sería imprimir en un objeto de archivo:
Sin embargo, redireccionar stdout también funciona para mí. Probablemente esté bien para un script único como este:
Redirigir externamente desde el propio shell es otra buena opción:
Otras preguntas:
¿Cuál es el primer nombre de archivo en su script? No lo veo inicializado.
Mi primera suposición es que glob no encuentra ningún archivo bam y, por lo tanto, el bucle for no se ejecuta. Compruebe que la carpeta existe e imprima archivos bam en su secuencia de comandos.
Además, use os.path.join y os.path.basename para manipular rutas y nombres de archivos.
fuente
Puede redirigir la impresión con el
>>
operador.En la mayoría de los casos, es mejor simplemente escribir en el archivo normalmente.
o, si tiene varios elementos que desea escribir con espacios entre ellos, como
print
:fuente
sys.stdout
, no es una buena idea.Dado que el objeto de archivo normalmente contiene un
write()
método, todo lo que necesita hacer es pasar un objeto de archivo a su argumento.Escribir / sobrescribir en archivo
Escribir / agregar al archivo
fuente
sys.stdout
:(Esto funciona perfectamente:
Ahora el saludo se escribirá en el archivo test.txt. Asegúrese de cerrar el archivo
stdout
con aclose
, sin él el contenido no se guardará en el archivofuente
sys.stdout.close()
, si escribe algo en Python Shell, mostrará el error comoValueError: I/O operation on closed file.
imgur.com/a/xby9P . La mejor manera de manejar esto es seguir lo que @Gringo Suave publicóNo uses
print
, usalogging
Puede cambiar
sys.stdout
para apuntar a un archivo, pero esta es una forma bastante torpe e inflexible de manejar este problema. En lugar de usarprint
, use ellogging
módulo.Con
logging
, puede imprimir como lo haríastdout
, o también puede escribir la salida en un archivo. Usted puede incluso utilizar los diferentes niveles de mensaje (critical
,error
,warning
,info
,debug
) para, por ejemplo, sólo imprimir las principales cuestiones a la consola, pero aún así registrar las acciones de código de menor importancia a un archivo.Un simple ejemplo
Importe
logging
, obtengalogger
y establezca el nivel de procesamiento:Si desea imprimir en stdout:
Si también desea escribir en un archivo (si solo desea escribir en un archivo, omita la última sección):
Luego, donde sea que use
print
usar uno de loslogger
métodos:Para obtener más información sobre el uso de
logging
funciones más avanzadas , lea el excelentelogging
tutorial en los documentos de Python .fuente
La solución más fácil no es a través de Python; es a través de la concha. Desde la primera línea de su archivo (
#!/usr/bin/python
) supongo que está en un sistema UNIX. Simplemente useprint
declaraciones como lo haría normalmente, y no abra el archivo en absoluto en su script. Cuando vayas a ejecutar el archivo, en lugar depara ejecutar el archivo, use
donde reemplaza
<filename>
con el nombre del archivo al que desea que vaya la salida. El>
token le dice a (la mayoría) los shells que establezcan stdout en el archivo descrito por el siguiente token.Una cosa importante que debe mencionarse aquí es que "script.py" debe hacerse ejecutable para
./script.py
ejecutarse.Entonces, antes de ejecutar
./script.py
, ejecute este comandochmod a+x script.py
(hacer que el script sea ejecutable para todos los usuarios)fuente
print
un archivo. Sería razonable esperar que stdout (trazas de pila y similares) aún se imprima en el terminal.Si está utilizando Linux, le sugiero que use el
tee
comando. La implementación es así:Si no desea cambiar nada en el código, creo que esta podría ser la mejor solución posible. También puede implementar el registrador, pero necesita hacer algunos cambios en el código.
fuente
Puede que no te guste esta respuesta, pero creo que es la CORRECTA. No cambie su destino stdout a menos que sea absolutamente necesario (tal vez esté usando una biblioteca que solo da salida a stdout, claramente no es el caso aquí).
Creo que, como buen hábito, debe preparar sus datos con anticipación como una cadena, luego abrir su archivo y escribir todo de una vez. Esto se debe a que las operaciones de entrada / salida son cuanto más tiempo tenga abierto un identificador de archivo, es más probable que ocurra un error con este archivo (error de bloqueo de archivo, error de E / S, etc.). Simplemente hacerlo todo en una sola operación no deja dudas sobre cuándo podría haber salido mal.
Aquí hay un ejemplo:
Y luego, cuando haya terminado de recopilar sus "líneas de datos" una línea por elemento de la lista, puede unirlas con algunos
'\n'
caracteres para que todo se pueda generar; tal vez incluso envuelva su declaración de salida en unwith
bloque, para mayor seguridad (cerrará automáticamente su identificador de salida incluso si algo sale mal):Sin embargo, si tiene muchos datos para escribir, puede escribirlos de a uno por vez. No creo que sea relevante para su aplicación, pero esta es la alternativa:
fuente
Si la redirección
stdout
funciona para su problema, la respuesta de Gringo Suave es una buena demostración de cómo hacerlo.Para hacerlo aún más fácil , hice una versión utilizando contextmanagers para una sintaxis de llamada generalizada sucinta usando la
with
declaración:Para usarlo, simplemente haga lo siguiente (derivado del ejemplo de Suave):
Es útil para redirigir selectivamente
print
cuando un módulo lo usa de una manera que no le gusta. La única desventaja (y este es el factor decisivo para muchas situaciones) es que no funciona si uno quiere múltiples hilos con diferentes valores destdout
, pero eso requiere un método mejor y más generalizado: acceso indirecto al módulo. Puede ver implementaciones de eso en otras respuestas a esta pregunta.fuente
Cambiar el valor de sys.stdout cambia el destino de todas las llamadas a imprimir. Si utiliza una forma alternativa de cambiar el destino de la impresión, obtendrá el mismo resultado.
Tu error está en otro lugar:
fuente
Algo para extender la función de impresión para bucles
fuente
while
y no es necesario cerrar el archivo cuando se usawith