Есть ли эквивалент Python для perl -pi -e`?

Я знаю 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 (свободная форма Tim Toady-ness), делает работу с perl -pi -e настолько хорошей, в то время как с Python вам нужно будет что-то делать по типу импорта модуля re, создавая повторный экземпляр, а затем захват stdin, но, возможно, есть ярлык Python, который делает все это, и я пропустил его (очень пропустил)...

Ответы

Ответ 1

Использование командной строки из 'python -h', безусловно, предполагает, что такого эквивалента нет. Perl имеет тенденцию широко использовать '$_' (ваши примеры неявно используют его), и я не думаю, что Python поддерживает любую аналогичную концепцию, тем самым делая более сложными эквиваленты Python для однострочных Perl.

Ответ 2

Python для маглов. Если вам нужна магия, Perl вы должны использовать!

Ответ 3

Эквивалент -pi не так сложно записать в Python.

  • Напишите себе удобный модуль с функциями -p и -i, которые вам действительно нравятся. Позвольте называть его pypi.py.

  • Используйте python -c 'import pypi; pypi.subs("this","that")'

Вы можете реализовать базовый цикл -p с помощью fileinput.

У вас будет функция subs, которая реализует необходимый алгоритм -i для открытия файла, сохранения резервной копии и выполнения замены в каждой строке.

Есть несколько рецептов активизации, подобных этому. Вот некоторые из них:

Не встроен. Но писать не сложно. И однажды написано легко настроить.

Ответ 4

Я знаю, что это уже несколько лет, но я недавно нашел очень хороший инструмент под названием pyp, что делает именно то, о чем вы просили.

Думаю, ваша команда должна быть:

pyp "p.replace('foo','bar')"

Ответ 5

Я думаю, что 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

Ответ 6

Модуль fileinput имеет возможность редактирования на месте. Однако вы не можете обойтись без резервных копий. Здесь, как использовать его для однострочного интерфейса:

python -c 'import fileinput, sys; for line in fileinput.input(inplace=True): sys.stdout.write(line, "foo", "bar")'

Лично я обычно использую Perl, когда мне нужно что-то делать. Это один из немногих случаев, когда я использую Perl.

Ответ 7

Вышеупомянутое может работать для stdin, но не похоже, что оно будет работать для файла.

Может быть что-то вроде:

-

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" )