Reputation: 12201
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
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
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
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
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
Reputation: 391862
An equivalent to -pi isn't that hard to write in Python.
Write yourself a handy module with the -p and -i features you really like. Let's call it pypi.py
.
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
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