Friday, October 19, 2012

Fun with IPython

Recently I had to git-rename (move) a few files according to a simple pattern (prepend "test_" to the name if it ends in ".py") and my shell fu had become rusty.  I wanted to do it in Python.

Enter IPython and its wonderful facility for mixing a little bit of shell goodness into your Python code.  Look what worked:

In [3]: fs = !ls

In [4]: fs
Out[4]: ['base.py', 'cache', '__init__.py', 'rss.py', 'util.py']

In [5]: for fn in fs:
   ...:     if fn.endswith('.py'):
   ...:         dest = 'test_' + fn
   ...:         !git mv $fn $dest
   ...:        

In [6]: !ls
cache  test_base.py  test___init__.py  test_rss.py  test_util.py
Neat, huh?

5 comments:

Jan Groenewald said...

While your filenames should not contain spaces, if they do it will break your code.

Replace dest = 'test_' + fn with
dest = 'test_' + fn.replace(' ', '_'), or change the git command to
!git mv "$fn" "$dest"

For reference, the bash is
for i in *.py; do git mv "$i" "test_$i"; done

David Ketcheson said...
This comment has been removed by the author.
Simon Forman said...

Oh hey! Comments on my blog post!? Huzzah! ^_^ I appreciate the bash stanza, that's exactly what I was trying to remember when I recalled Ipython's '!' magic. And yes, only truly evil people put spaces in their file names.

Dmitri said...

Based on vidir from moreutils, I made a "git-vidir" which makes these sorts of edits really easy (they degenerate to file edits in vim, or your editor of choice). Unlike the Python script, you get to review the changes before effecting them.

Dmitri said...

What I meant was, I just copied vidir and replaced the unlink and rename calls with git directives. It's only slightly better than just using vidir directly and then git add / git commit -a. vidir itself is the real winner.

More people need to know about vidir :)