Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 563
Silfheed Avatar asked Dec 14 '08 22:12

Silfheed


3 Answers

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.

like image 68
Jonathan Leffler Avatar answered Oct 20 '22 17:10

Jonathan Leffler


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:

  • http://code.activestate.com/recipes/437932/
  • http://code.activestate.com/recipes/435904/
  • http://code.activestate.com/recipes/576537/

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

like image 10
S.Lott Avatar answered Oct 20 '22 15:10

S.Lott


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')"
like image 9
jarondl Avatar answered Oct 20 '22 15:10

jarondl