views:

768

answers:

4

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

+13  A: 

Python is for muggles. If magic you want, Perl you should use!

Igal Serban
+6  A: 

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.

Jonathan Leffler
+5  A: 

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.

S.Lott
I would suggest that the module is called pi.py, is stored inside the site-packages directory, ends with a `if __name__ == "__main__":` construct, and then called with `python -mpi <arg> <arg>...`
ΤΖΩΤΖΙΟΥ
+6  A: 

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
monkut
This really is in no way a replacement for a one-liner, and hence most of this is not an answer to the question
Leon Timmermans
Yes, but perhaps the more elegant solution isn't the equivelent to `perl -pi -e`, but writing your own command line tools for often performed tasks. "myscript.py -x this -y that" may be cleaner than "python -c 'import this; dostuff(this,that)'". It depends on your individual needs and preferences.
monkut