У меня есть несколько скриптов Python, и я работаю над их переписыванием. У меня та же проблема со всеми из них.
Для меня не очевидно, как писать программы, чтобы они вели себя как надлежащие инструменты Unix.
Потому что это
$ cat characters | progname
и это
$ progname characters
должен выдавать тот же результат.
Наиболее близкой вещью, которую я смог найти в Python, была библиотека fileinput. К сожалению, я не вижу, как переписать мои скрипты Python, все из которых выглядят так:
#!/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
Библиотека fileinput обрабатывает stdin, если есть stdin, и обрабатывает файл, если есть файл. Но он повторяется по одной строке.
import fileinput
for line in fileinput.input():
process(line)
Я действительно не понимаю этого. Я думаю, если вы имеете дело с небольшими файлами, или если вы не слишком много делаете для файлов, это может показаться очевидным. Но для моих целей это намного медленнее, чем просто открыть весь файл и прочитать его в строку, как описано выше.
В настоящее время я запускаю скрипт выше, как
$ pythonscript textfilename1 > textfilename2
Но я хочу быть в состоянии запустить его (и его братьев) в трубах, как
$ grep pattern textfile1 | pythonscript | pythonscript | pythonscript > textfile2
Ответы:
Почему не просто
источник
sys.stdin
следует использовать вместо этого, поскольку он более переносим, чем жестко заданный путь к файлу.sys.stdin
следует использовать вместо этого, как говорит Петрsys.stdin
это файл, и он уже открыт, и не должен быть закрыт. Невозможно обработать, как аргумент файла, не перепрыгивая через обручи.f
или использовать менеджер контекста, вам нужно что-то более сложное. Смотрите мой новый ответ в качестве альтернативы.Проверьте, задано ли имя файла в качестве аргумента или прочитано из
sys.stdin
.Что-то вроде этого:
Это похоже на ответ Микеля, за исключением того, что он использует
sys
модуль. Я полагаю, если у них есть это там, это должно быть по причине ...источник
"open(/dev/stdin")
сsys.stdin
.if len(sys.argv)>1:
вместо того, чтобыif sys.argv[1]:
иначе вы получили ошибку индекса вне диапазонаМой предпочтительный способ сделать это оказывается ... (и это взято из милого небольшого блога Linux под названием Harbinger's Hollow )
Причина, по которой мне это понравилось больше всего, заключается в том, что, как говорит блоггер, он просто выводит глупое сообщение, если случайно вызывается без ввода. Он также так хорошо вписывается во все мои существующие скрипты Python, что я изменил их все, чтобы включить.
источник
isatty
и выручка не соответствуют философии Unix-фильтров.isatty
бородавки, это охватывает полезную и важную почву, которой нет в других ответах, так что это вызывает у меня одобрение.источник
/dev/stdin
был недоступен на всех моих системах.Я использую это решение, и оно работает как шарм. На самом деле я использую в скрипте Каллы unaccent , что нижний регистр и удаляют акценты из заданной строки
Я думаю, самое жаркое время, когда я увидел это решение, было здесь .
источник
Если ваша система не имеет
/dev/stdin
или вы хотите более общее решение, вы можете попробовать что-то более сложное, например:источник
-
несколько раз. :)