Saya memiliki beberapa skrip Python yang bertebaran, dan saya sedang mengerjakan penulisan ulang. Saya memiliki masalah yang sama dengan mereka semua.
Tidak jelas bagi saya bagaimana menulis program sehingga mereka berperilaku seperti alat unix yang tepat.
Karena ini
$ cat characters | progname
dan ini
$ progname characters
harus menghasilkan output yang sama.
Hal terdekat yang dapat saya temukan dengan Python adalah perpustakaan fileinput. Sayangnya, saya tidak benar-benar melihat cara menulis ulang skrip Python saya, yang semuanya terlihat seperti ini:
#!/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
Perpustakaan fileinput memproses stdin jika ada stdin, dan memproses file jika ada file. Tapi iterates lebih dari satu baris.
import fileinput
for line in fileinput.input():
process(line)
Saya benar-benar tidak mengerti. Saya kira jika Anda berurusan dengan file kecil, atau jika Anda tidak berbuat banyak untuk file, ini mungkin tampak jelas. Tapi, untuk tujuan saya, ini membuatnya jauh lebih lambat daripada hanya membuka seluruh file dan membacanya menjadi string, seperti di atas.
Saat ini saya menjalankan script seperti di atas
$ pythonscript textfilename1 > textfilename2
Tapi saya ingin bisa menjalankannya (dan saudara-saudaranya) di pipa, seperti
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
Jawaban:
Kenapa tidak adil?
sumber
sys.stdin
harus digunakan sebagai gantinya karena lebih portabel daripada jalur hardcoded ke file.sys.stdin
harus digunakan sebagai gantinya, seperti kata Piotrsys.stdin
ini file, dan sudah terbuka, dan tidak boleh ditutup. Tidak mungkin untuk menangani seperti argumen file tanpa melewati rintangan.f
, atau ingin menggunakan manajer konteks, Anda memerlukan sesuatu yang lebih kompleks. Lihat jawaban baru saya sebagai alternatif.Periksa apakah nama file diberikan sebagai argumen, atau dibaca
sys.stdin
.Sesuatu seperti ini:
Ini mirip dengan jawaban Mikel kecuali ia menggunakan
sys
modul. Saya pikir jika mereka memilikinya di sana pasti karena suatu alasan ...sumber
"open(/dev/stdin")
dengansys.stdin
.if len(sys.argv)>1:
alih-alihif sys.argv[1]:
jika tidak, Anda mendapatkan indeks di luar rentang kesalahanCara yang saya sukai untuk melakukannya ternyata ... (dan ini diambil dari blog Linux kecil yang menyenangkan bernama Harbinger's Hollow )
Alasan mengapa saya paling menyukai ini adalah, seperti yang dikatakan blogger, itu hanya menghasilkan pesan konyol jika tidak sengaja dipanggil tanpa masukan. Ini juga slot begitu baik ke semua skrip Python saya yang ada sehingga saya telah memodifikasi semuanya untuk memasukkannya.
sumber
isatty
dan membatalkan tidak sesuai dengan filosofi filter Unix.isatty
kutil, ini mencakup dasar yang berguna dan penting yang tidak ditemukan dalam jawaban lain, sehingga mendapat saya upvote.sumber
/dev/stdin
tidak tersedia di semua sistem saya.Saya menggunakan solusi ini dan berfungsi seperti pesona. Sebenarnya saya menggunakan dalam script calle unaccent yang menurunkan dan menghilangkan aksen dari string yang diberikan
Saya kira waktu terberat saya melihat solusi ini ada di sini .
sumber
Jika sistem Anda tidak memiliki
/dev/stdin
, atau Anda menginginkan solusi yang lebih umum, Anda dapat mencoba sesuatu yang lebih rumit seperti:sumber
-
beberapa kali. :)