Я знаю python -c '<code>', но мне интересно, есть ли более элегантный эквивалент perl -pi -e '<code>' на питоне. Я все еще довольно часто использую его для таких вещей, как поиск и замена во всем каталоге (perl -pi -e s/foo/bar/g * или даже find . | xargs perl -pi -e s/foo/bar/g для подкаталогов).
Я действительно чувствую, что именно то, что делает Perl Perl (свободная форма Тим Тоади-несс), заставляет perl -pi -e работать так хорошо, в то время как с Python вам нужно будет что-то вроде импорта модуля re, создания повторного экземпляра, а затем захватить stdin, но, возможно, есть ярлык Python, который делает все это, и я его пропустил (очень пропустил) ...
Наверняка вы имеете в виду найти. -тип f | xargs perl ...?
Вместо этого вы можете использовать Ruby. В Ruby эквивалентом perl -pi -e является ruby -pi -e. Щелкните эта ссылка для получения дополнительной информации.






Использование командной строки из python -h, безусловно, указывает на то, что такого эквивалента не существует. Perl имеет тенденцию широко использовать «$_» (в ваших примерах он используется неявно), и я не думаю, что Python поддерживает какую-либо подобную концепцию, что значительно усложняет Python-эквиваленты однострочников Perl.
Эквивалент -pi несложно написать на Python.
Напишите себе удобный модуль с функциями -p и -i, которые вам действительно нравятся. Назовем его pypi.py.
Используйте python -c 'import pypi; pypi.subs("this","that")'
Вы можете реализовать базовый цикл -p с помощью модуля ввод файла.
У вас будет функция subs, которая реализует основной алгоритм «-i» открытия файла, сохранения резервной копии и выполнения замены в каждой строке.
Есть несколько таких рецептов активного состояния. Вот некоторые:
Не встроен. Но написать не сложно. А когда-то написано, легко настраивается.
Я бы предположил, что модуль называется pi.py, хранится в каталоге site-packages, заканчивается конструкцией if __name__ == "__main__":, а затем вызывается с помощью python -mpi <arg> <arg>....
Я думаю, что Perl лучше подходит для такого рода сценариев «на лету». Если вам нужна возможность быстрого создания разовых сценариев на лету, я рекомендую придерживаться perl, awk, sed и стандартных инструментов командной строки unix.
Но если вы заинтересованы в использовании Python, я использую optparse для написания собственных инструментов командной строки и рекомендую его. optparse предоставляет чистый и простой в использовании синтаксический анализатор параметров командной строки со встроенным генератором справки.
Вот образец:
def myfunc(filename, use_versbose):
# function code
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-f", "--file", dest = "filename",
help = "write report to FILE", metavar = "FILE")
parser.add_option("-q", "--quiet",
action = "store_false", dest = "verbose", default=True,
help = "don't print status messages to stdout")
(options, args) = parser.parse_args()
if options.filename:
myfunc(options.filename, options.verbose)
else:
print 'ERROR -- Necessary command line options not given!'
print parser.print_help()
parser.print_help () генерирует следующий вывод и автоматически отображается при вводе -h или --help в командной строке:
usage: <yourscript> [options]
options:
-h, --help show this help message and exit
-f FILE, --file=FILE write report to FILE
-q, --quiet don't print status messages to stdout
Это действительно никоим образом не замена однострочному, и, следовательно, большая часть этого не является ответом на вопрос
Да, но, возможно, более элегантное решение - это не эквивалент perl -pi -e, а написание собственных инструментов командной строки для часто выполняемых задач. «myscript.py -x this -y that» может быть чище, чем «python -c 'import this; dostuff (this, that)'». Это зависит от ваших индивидуальных потребностей и предпочтений.
Модуль fileinput имеет возможность редактирования на месте. Однако вы не можете обойтись без резервных копий. Вот как использовать его для однострочника:
python -c 'import fileinput, sys; for line in fileinput.input(inplace=True): sys.stdout.write(line, "foo", "bar")'
Лично я обычно использую Perl, когда мне нужно сделать что-то подобное. Это один из немногих случаев, когда я использую Perl.
Я знаю, что это на пару лет слишком поздно, но недавно я нашел очень хороший инструмент под названием pyp, который делает именно то, о чем вы просили.
Я думаю, ваша команда должна быть:
pyp "p.replace('foo','bar')"
Хорошая находка! pyp («Pyed Piper, конвейер Python через конвейеры») от Sony Pictures Imageworks, очень краткий, гибкий, может выполнять статистику, внутренние конвейеры и т. д. Он был представлен на PYCON 2012 «The Pyed Piper: современная альтернатива Python для awk, sed и другие утилиты для работы с текстом Unix от Тоби Розена "
Поддерживается ли код pypi.py? Python 3? Я посмотрел видео и архивы, которые мне удалось найти, датируются 2012-2015 годами - не нашел ничего более свежего. Я упускаю из виду очевидное (например, «это не нужно поддерживать - это просто работает»)?
Вышеупомянутое может работать для стандартного ввода, но не похоже, что оно будет работать для файла.
Может быть, что-то вроде:
-
import fileinput
import sys
for line in fileinput.input("./poop", inplace=True):
line = line.replace("foo", "bar")
sys.stdout.write(line)
- где "./poop" можно заменить на то, где находится ваш файл, а line.replace должен поддерживать такие вещи, как line.replace ("{}". format (variablehere), "newtext")
Честно говоря, это звучит так, будто Гвидо не одобрил бы это.