Silfheed
Silfheed

Reputation: 12201

Is there a Python equivalent to `perl -pi -e`?

I know of python -c '<code>', but I'm wondering if there's a more elegant python equivalent to perl -pi -e '<code>'. I still use it quite a bit for things like find and replace in a whole directory (perl -pi -e s/foo/bar/g * or even find . | xargs perl -pi -e s/foo/bar/g for sub-directories).

I actually feel that that which makes Perl Perl (free form Tim Toady-ness) is what makes perl -pi -e work so well, while with Python you'd have to do something along the lines of importing the re module, creating an re instance and then capture stdin, but maybe there's a Python shortcut that does all that and I missed it (sorely missed it)...

Upvotes: 18

Views: 3523

Answers (6)

cgseller
cgseller

Reputation: 4043

The above may work for stdin, but does not look like it would work for a file.

Maybe something like:

--

import fileinput 
import sys
for line in fileinput.input("./poop", inplace=True):
    line = line.replace("foo", "bar")
    sys.stdout.write(line)

-- where "./poop" can be replaced with where your file is and line.replace should support things like line.replace("{}".format(variablehere),"newtext")

Upvotes: 0

jarondl
jarondl

Reputation: 1663

I know this is a couple of years too late, but I've recently found a very nice tool called pyp, which does exactly what you've asked for.

I think your command should be:

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

Upvotes: 10

Michael Hoffman
Michael Hoffman

Reputation: 34334

The fileinput module has the capability for in-place editing. You can't dispense with the backups, though. Here's how to use it for a one-liner:

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

Personally, I just usually use Perl when I need to do something like this. It is one of the few times I use Perl.

Upvotes: 2

monkut
monkut

Reputation: 43840

I think perl is better suited for this kind of on the fly scripting. If you want quick on the fly one-off scripting capability I recommend sticking to perl, awk, sed, and standard unix command-line tools.

But if your interested in using python, I use optparse to write my own command line tools and recommend it. optparse provides a clean and easy-to-use command line option parser with built in help generation.

Here's a sample:

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() generates the following output, and is automatically displayed when -h or --help is given at the command line:

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

Upvotes: 6

S.Lott
S.Lott

Reputation: 391862

An equivalent to -pi isn't that hard to write in Python.

  1. Write yourself a handy module with the -p and -i features you really like. Let's call it pypi.py.

  2. Use python -c 'import pypi; pypi.subs("this","that")'

You can implement the basic -p loop with the fileinput module.

You'd have a function, subs that implements the essential "-i" algorithm of opening a file, saving the backup copy, and doing the substitute on each line.

There are some activestate recipes like this. Here are some:

Not built-in. But not difficult to write. And once written easy to customize.

Upvotes: 10

Jonathan Leffler
Jonathan Leffler

Reputation: 754060

The command line usage from 'python -h' certainly strongly suggests there is no such equivalent. Perl tends to make extensive use of '$_' (your examples make implicit use of it), and I don't think Python supports any similar concept, thereby making Python equivalents of the Perl one-liners much harder.

Upvotes: 10

Related Questions