txt partir modificar lista leer importar gestion formas espaƱol ejercicios crear como binarios archivos archivo python file command-line arguments stdin

python - partir - Leer desde archivo, o STDIN



modificar txt python (7)

He escrito una utilidad de línea de comandos que usa getopt para analizar argumentos dados en la línea de comando. También me gustaría que un nombre de archivo sea un argumento opcional, como lo es en otras utilidades como grep, cut, etc. Por lo tanto, me gustaría que tenga el siguiente uso

tool -d character -f integer [filename]

¿Cómo puedo implementar lo siguiente?

  • si se da un nombre de archivo, lee del archivo.
  • si no se proporciona un nombre de archivo, lea de STDIN.

Algo como:

if input_from_file: f = open(file_name, "rt") else: f = sys.stdin inL = f.readline() while inL: print inL.rstrip() inL = f.readline()


El módulo de entrada de fileinput puede hacer lo que quiera; suponiendo que los argumentos que no son de opción están en args entonces:

import fileinput for line in fileinput.input(args): print line

Si args está vacío, fileinput.input() leerá desde stdin; de lo contrario, se lee de cada archivo uno por uno, de manera similar a Perl''s while(<>) .


En los términos más simples:

import sys # parse command line if file_name_given: inf = open(file_name_given) else: inf = sys.stdin

En este punto, usaría inf para leer del archivo. Dependiendo de si se dio un nombre de archivo, esto se leería desde el archivo dado o desde stdin.

Cuando necesite cerrar el archivo, puede hacer esto:

if inf is not sys.stdin: inf.close()

Sin embargo, en la mayoría de los casos será inofensivo cerrar sys.stdin si ya ha terminado.


Me gusta el lenguaje general de usar un administrador de contexto, pero la solución (demasiado) trivial termina cerrando sys.stdin cuando está fuera de la declaración with , que quiero evitar.

Tomando prestado de esta respuesta , aquí hay una solución alternativa:

import sys import contextlib @contextlib.contextmanager def _smart_open(filename, mode=''Ur''): if filename == ''-'': if mode is None or mode == '''' or ''r'' in mode: fh = sys.stdin else: fh = sys.stdout else: fh = open(filename, mode) try: yield fh finally: if filename is not ''-'': fh.close() if __name__ == ''__main__'': args = sys.argv[1:] if args == []: args = [''-''] for filearg in args: with _smart_open(filearg) as handle: do_stuff(handle)

Supongo que podrías lograr algo similar con os.dup() pero el código que os.dup() para hacer eso resultó ser más complejo y más mágico, mientras que lo anterior es un tanto torpe pero muy directo.


No respuesta directa pero relacionada.

Normalmente, cuando escribe un script de python puede usar el paquete argparse . SI este es el caso que puede usar:

parser = argparse.ArgumentParser() parser.add_argument(''infile'', nargs=''?'', type=argparse.FileType(''r''), default=sys.stdin)

''?''. De ser posible, se consumirá un argumento de la línea de comando y se producirá como un único elemento. Si no hay un argumento de línea de comandos presente, se generará el valor predeterminado.

y aquí establecemos el valor predeterminado para sys.stdin ;

entonces, si hay un archivo, lo leerá, y si no, tomará la entrada de stdin "Nota: que estamos usando un argumento posicional en el ejemplo anterior"

para obtener más visita: https://docs.python.org/2/library/argparse.html#nargs


Para hacer uso de la declaración de python with , uno puede usar el siguiente código:

import sys with open(sys.argv[1], ''r'') if len(sys.argv) > 1 else sys.stdin as f: # read data using f # ......


Prefiero usar "-" como indicador de que debe leer de stdin, es más explícito:

import sys with open(sys.argv[1], ''r'') if sys.argv[1] is not "-" else sys.stdin as f: pass # do something here