J'ai quelques scripts Python qui traînent et je travaille à les réécrire. J'ai le même problème avec chacun d'eux.
Il n'est pas évident pour moi d'écrire les programmes pour qu'ils se comportent comme des outils Unix appropriés.
Car ce
$ cat characters | progname
et ça
$ progname characters
devrait produire la même sortie.
La chose la plus proche que j'ai pu trouver en Python était la bibliothèque d'entrée de fichiers. Malheureusement, je ne vois pas vraiment comment réécrire mes scripts Python, qui ressemblent tous à ceci:
#!/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 bibliothèque fileinput traite stdin s'il y a un stdin et traite un fichier s'il y a un fichier. Mais il itère sur des lignes simples.
import fileinput
for line in fileinput.input():
process(line)
Je ne comprends vraiment pas cela. Je suppose que si vous traitez de petits fichiers ou si vous ne faites pas grand-chose avec les fichiers, cela peut sembler évident. Mais, pour mes besoins, cela est beaucoup plus lent que d'ouvrir simplement le fichier entier et de le lire dans une chaîne, comme ci-dessus.
Actuellement, je lance le script ci-dessus comme
$ pythonscript textfilename1 > textfilename2
Mais je veux pouvoir le faire fonctionner (et ses frères) dans des tuyaux, comme
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
Réponses:
Pourquoi pas
la source
sys.stdin
devrait être utilisé à la place car il est plus portable que le chemin d'accès au fichier en dur.sys.stdin
devrait être utilisé à la place, comme le dit Piotrsys.stdin
c'est un fichier, et il est déjà ouvert, et ne doit pas être fermé. Impossible de gérer comme un argument de fichier sans sauter à travers des cerceaux.f
ou utiliser un gestionnaire de contexte, vous avez besoin de quelque chose de plus complexe. Voir ma nouvelle réponse comme une alternative.Vérifiez si un nom de fichier est donné comme argument, ou bien lisez
sys.stdin
.Quelque chose comme ça:
C'est similaire à la réponse de Mikel, sauf qu'il utilise le
sys
module. Je pense que s'ils l'ont, ça doit être pour une raison ...la source
"open(/dev/stdin")
parsys.stdin
.if len(sys.argv)>1:
au lieu deif sys.argv[1]:
sinon vous obtenez une erreur d'index hors plageMa façon préférée de le faire se révèle être ... (et cela est tiré d'un joli petit blog Linux appelé Harbinger's Hollow )
La raison pour laquelle j'ai préféré cela, c'est que, comme le dit le blogueur, il émet simplement un message stupide s'il est accidentellement appelé sans entrée. Il s'intègre également si bien dans tous mes scripts Python existants que je les ai tous modifiés pour l'inclure.
la source
isatty
et le renflouement ne sont pas conformes à la philosophie des filtres Unix.isatty
verrue, cela couvre un terrain utile et important qui ne se trouve pas dans les autres réponses, donc cela obtient mon vote positif.la source
/dev/stdin
n'était pas disponible sur tous mes systèmes.J'utilise cette solution et cela fonctionne comme un charme. En fait, j'utilise dans un script calle unaccent qui minuscule et supprime les accents d'une chaîne donnée
Je suppose que la première fois que j'ai vu cette solution était ici .
la source
Si votre système n'en a pas
/dev/stdin
, ou si vous voulez une solution plus générale, vous pouvez essayer quelque chose de plus compliqué comme:la source
-
plusieurs fois. :)