Ich habe ein paar Python-Skripte herumliegen, und ich arbeite daran, sie umzuschreiben. Ich habe mit allen das gleiche Problem.
Mir ist nicht klar, wie man die Programme so schreibt, dass sie sich wie richtige Unix-Tools verhalten.
Weil das
$ cat characters | progname
und das
$ progname characters
sollte die gleiche Ausgabe erzeugen.
Das Nächste, was ich in Python finden konnte, war die Dateieingabebibliothek. Leider sehe ich nicht wirklich, wie ich meine Python-Skripte umschreiben kann, die alle so aussehen:
#!/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
Die Dateieingabebibliothek verarbeitet stdin, wenn es eine stdin gibt, und verarbeitet eine Datei, wenn es eine Datei gibt. Es wird jedoch über einzelne Zeilen iteriert.
import fileinput
for line in fileinput.input():
process(line)
Das verstehe ich wirklich nicht. Ich denke, wenn Sie mit kleinen Dateien zu tun haben oder wenn Sie nicht viel mit den Dateien tun, scheint dies offensichtlich zu sein. Für meine Zwecke ist dies jedoch viel langsamer als das einfache Öffnen der gesamten Datei und das Einlesen in eine Zeichenfolge, wie oben.
Zur Zeit starte ich das obige Skript gerne
$ pythonscript textfilename1 > textfilename2
Aber ich möchte in der Lage sein, es (und seine Brüder) in Rohren zu betreiben
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
Antworten:
Warum nicht einfach
quelle
sys.stdin
sollte stattdessen verwendet werden, da es portabler ist als der fest codierte Pfad zur Datei.sys.stdin
sollte stattdessen verwendet werden, wie Piotr sagtsys.stdin
ist eine Datei, und es ist bereits geöffnet und darf nicht geschlossen werden. Es ist unmöglich, ein Argument wie eine Datei zu behandeln, ohne durch die Rahmen zu springen.f
oder einen Kontextmanager verwenden möchten, benötigen Sie etwas Komplexeres. Siehe meine neue Antwort als Alternative.Überprüfen Sie, ob ein Dateiname als Argument angegeben oder aus diesem gelesen wurde
sys.stdin
.Etwas wie das:
Es ist ähnlich wie die Antwort von Mikel, außer dass es das
sys
Modul verwendet. Ich denke, wenn sie es da drin haben, muss es einen Grund haben ...quelle
"open(/dev/stdin")
durchsys.stdin
.if len(sys.argv)>1:
anstattif sys.argv[1]:
sonst erhalten Sie einen Index außerhalb des Bereichs FehlerMeine bevorzugte Vorgehensweise ist ... (und diese stammt aus einem netten kleinen Linux-Blog namens Harbinger's Hollow )
Der Grund, warum mir das am besten gefallen hat, ist, dass es, wie der Blogger sagt, nur eine dumme Nachricht ausgibt, wenn es versehentlich ohne Eingabe aufgerufen wird. Es fügt sich auch so gut in alle meine vorhandenen Python-Skripte ein, dass ich sie alle so modifiziert habe, dass sie es enthalten.
quelle
isatty
und Rettung entsprechen nicht der Philosophie von Unix-Filtern.isatty
Warze deckt dies nützlichen und wichtigen Grund ab, der in den anderen Antworten nicht zu finden ist, so dass es meine Zustimmung erhält.quelle
/dev/stdin
es nicht auf allen meinen Systemen verfügbar gewesen wäre.Ich benutze diese Lösung und es funktioniert wie ein Zauber. Eigentlich verwende ich in einem Skript calle unaccent , das Akzente in einer bestimmten Zeichenfolge herabsetzt und entfernt
Ich denke, die beste Zeit, als ich diese Lösung sah, war hier .
quelle
Wenn Ihr System über keine
/dev/stdin
oder eine allgemeinere Lösung verfügt, können Sie etwas Komplizierteres ausprobieren:quelle
-
mehrere Male zu verwenden. :)