Comment lire du texte avec une entrée standard ou une spécification de nom de fichier comme cat en Python

Les commandes telles que cat sont lues avec le nom de fichier comme argument, mais si aucun nom de fichier n'est donné, l'entrée standard est lue. Cette fois, j'ai étudié comment y parvenir avec Python.

$ cat input.txt
$ cat < input.txt
$ python hoge.py input.txt
$ python hoge.py < input.txt

0. Basique

En Python, l'entrée standard et le pointeur vers le fichier texte sont des objets fichier (plus spécifiquement, des instances de la classe _io.TextIOWrapper), donc les fonctions suivantes fonctionneront même si l'entrée standard sys.stdin est donnée en argument. Je vais.

def process(fp):
    for line in fp:
        print(line, end='')

Que fait cet article avec ce processus externe? Sur ce, nous considérerons trois méthodes.

1. Classification simple des cas

hoge.py



import argparse
import sys


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('filename', nargs='?')
    args = parser.parse_args()

    if args.filename is None:
        process(sys.stdin)
    else:
        with open(args.filename) as f:
            process(f)

if __name__ == "__main__":
    main()

C'est un moyen simple de créer des branches selon qu'un argument de ligne de commande est donné. Dans cet article, nous ne considérons pas la gestion spéciale des exceptions pour ʻOSErrorlors de l'exécution de ʻopen ()ouprocess (), mais fermons le fichier même lorsqu'une exception se produit dansprocess (). C'est un must. Si vous ajoutez ʻargparseici, si vous ometteznargs = '?', Filename` sera requis.

Cette méthode est très simple à comprendre, mais ce qui n’est pas surprenant, c’est que «process ()» est décrit à deux endroits. Avec un peu plus d'ingéniosité, il peut être assemblé en un seul endroit, mais if-else se sent toujours un peu redondant.

  1. argparse.Filetype()

hoge.py


import argparse
import sys


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', nargs='?', type=argparse.FileType(),
                        default=sys.stdin)
    args = parser.parse_args()
    with args.infile as f:
        process(f)

C'est un peu inconnu, mais dans l'ensemble, c'est très rafraîchissant.

En définissant type = argparse.FileType (), ʻopen () est appelé au moment de parse_args () et sa valeur de retour est stockée. À ce stade, si le nom de fichier donné est -, il sera converti en entrée / sortie standard. Par conséquent, si vous définissez default = '-', la description sera un peu réduite et ʻimport sys sera inutile, mais il est difficile à comprendre pour les étrangers, et [Document exemple](https: // docs. python.org/ja/3/library/argparse.html) indique également explicitement default = sys.stdin.

Et il est normal d'écrire ʻopen () immédiatement après with`, mais la valeur de retour est la même même pour l'objet fichier lui-même, donc l'opération est la même. Bien que l'importance d'utiliser «comme» soit diminuée.

sys.stdin n'est généralement pas dérangé d'être utilisé avec l'instruction with ou d'appelerclose (), mais il est bien défini car il s'agit d'un TextIOWrapper. Il est probablement utilisé dans un tel cas. (Source requise)

  1. argparse + fileinput Je pense que c'est un cas rare, mais il y a des moments où vous voulez pouvoir spécifier plusieurs noms de fichiers et les lire un fichier à la fois, ou utiliser une entrée standard si aucun n'est spécifié. Dans un tel cas, il est facile d'utiliser ensemble le module fileinput.

hoge.py


import argparse
import fileinput


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('filenames', nargs='*')
    args = parser.parse_args()
    with fileinput.input(args.filenames) as f:
        process(f)

fileinput.input () ouvre les noms de fichiers énumérés les uns après les autres et les convertit en entrée standard si aucun nom de fichier n'est donné.

Même si - est spécifié comme nom de fichier, l'entrée standard est appelée, donc si vous exécutez $ python hoge.py input.txt - etc., l'entrée standard sera lue après la lecture de input.txt. Eh bien, ce ne sera pas un gros problème!

Personnellement, je pense que la difficulté est que ce module d'entrée de fichier semble prendre en charge l'entrée standard si vous ne le connaissez pas. Il n'y a pas de place. Je ne pense pas que ce soit un module aussi célèbre ...

Résumé

Je pense qu'il est préférable d'utiliser la méthode 2 lors de la lecture d'un fichier ** ou ** entrée standard, et la méthode 3 lors de la lecture de plusieurs fichiers ** ou ** entrée standard.

(23/11 postscript) Cliquez ici si vous voulez lire plusieurs fichiers en même temps → [Comment lire des fichiers d'entrée standard ou des fichiers de variables en même temps comme la commande coller en Python](https://qiita.com/hi-asano/ items / de83b18ce4365dd6f793)

Question

Si vous essayez de faire la même chose dans une autre langue, vous devez généralement le faire avec if-else like 1, ce qui est assez difficile? Perl semble être facile.

Recommended Posts

Comment lire du texte avec une entrée standard ou une spécification de nom de fichier comme cat en Python
Comment lire des entrées standard ou des fichiers variables en même temps comme la commande coller en Python
[Python] Changer l'entrée standard du clavier en fichier texte
Comment changer le fichier de configuration pour qu'il soit lu par Python
Comment importer des fichiers où vous le souhaitez en Python
Lisez le fichier ligne par ligne avec Python
Lisez le fichier ligne par ligne avec Python
Comment lire un fichier CSV avec Python 2/3
Comment créer un fichier JSON en Python
[Python] Comment lire des fichiers Excel avec des pandas
Comment générer "Ketsumaimo" en standard en Python
Comment lire des fichiers dans différents répertoires
Comment lire toutes les classes contenues dans * .py dans le répertoire spécifié par Python
Comment obtenir le nom de la variable lui-même en python
Comment mesurer le temps de traitement avec Python ou Java
Lisez le fichier xml en vous référant au didacticiel Python
[Efficacité du travail] Comment changer les noms de fichiers par lots avec Python
Comment lire un csv contenant uniquement des entiers en Python
Comment déboguer une bibliothèque Python standard dans Visual Studio
Changer la destination de sortie standard en un fichier en Python
Parler avec Python [synthèse vocale]
[Python] Comment changer le fichier EXCEL enregistré dans xlsb en xlsx
Comment développer en Python
[Python] Lire les arguments de ligne de commande à partir du nom de fichier ou de stdin
Comment lire un fichier Excel (.xlsx) avec Pandas [Python]
[Python] Comment utiliser input ()
Convertir un fichier Excel en texte en Python à des fins de comparaison
Comment transformer une chaîne en tableau ou un tableau en chaîne en Python
Comment déterminer qu'une clé croisée a été entrée dans Python3
Lire la sortie standard d'un sous-processus ligne par ligne en Python
[Django] Comment lire les variables / constantes définies dans un fichier externe
[Python] Comment faire PCA avec Python
Comment collecter des images en Python
Comment utiliser SQLite en Python
Comment utiliser Mysql avec python
Comment envelopper C en Python
Comment utiliser ChemSpider en Python
Comment utiliser PubChem avec Python
Comment gérer le japonais avec Python
Comment saisir une chaîne de caractères en Python et la sortir telle quelle ou dans la direction opposée.
[Python Kivy] Comment obtenir le chemin du fichier par glisser-déposer
[Python] Comment mettre n'importe quel nombre d'entrées standard dans la liste
Comment stocker des données CSV dans Amazon Kinesis Streams avec une entrée standard
[Python] Comment lire le fichier csv (méthode read_csv du module pandas)
Le nom du fichier était mauvais en Python et j'étais accro à l'importation
Comment bien formater une liste de dictionnaires (ou d'instances) en Python
Comment lire les variables d'environnement à partir d'un fichier .env avec PyCharm (pour Mac)
Comment trier en spécifiant une colonne dans le tableau Python Numpy.
Que faire lorsque la version Python est ancienne dans Cloud 9 créée par une autre personne
[Python] Comment convertir un fichier db en csv
Comment générer un code QR et un code à barres en Python et le lire normalement ou en temps réel avec OpenCV
[Introduction à Python] Comment utiliser la classe en Python?
Comment lire pydoc sur l'interpréteur python
Comment définir dynamiquement des variables en Python
Comment faire R chartr () en Python
python Remarque: Modularisation: __name__ == Comment utiliser '__ main__'
Comment convertir Python en fichier exe
[Itertools.permutations] Comment créer une séquence en Python
Convertir un fichier psd en png en Python
Entrée standard Python3 que j'ai essayé de résumer