Selectively changing case using sed
July 2, 2008
I was faced today with a situation where I had to convert Qt4 style (???) includes:
#include <QMap>
with Qt3 style includes:
#include <qmap.h>
while trying to see if I could port some of my changes to the GSoC branch of KStars to the KDE 3.5.9 version. Of course, I may be overlooking at a lot of impossibilities in making the shift, but there’s not much harm in trying - only new learning :D.
So how would one do that? I searched around a bit here and there and got the solution, in bits and pieces, so I thought I should blog about it. The flow should go like this: First match include <Q\([^>]*\)> and substitute it with include <q\1.h>. That will replace #include <QMap> with #include <qMap.h>. But that’s not enough. We need to get qmap.h instead.
A first (dumb) attempt would be to pipe the output of sed through tr and tell it to translate [:upper:] to [:lower:], but that would translate everything. But “translate” is the key word. Search around a bit and you’ll find that sed has a translate command. To translate [:upper:] to [:lower:], you will need to do:
sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'
Because sed doesn’t support regular expressions or POSIX groups for translation. (Referred here)
But that will give me the same output as tr would. I want something more sophisticated - I want to convert only those lines which matched my initial substitution. Some more searching around (”conditional sed” were the keywords) and man sed told me that I could do “if( not substituted ) goto end;” by using the ‘T‘ command. So the whole things boils down to this:
sed ’s/include <Q\([^>]*\)>/include <q\1.h>/;T;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/’
Here’s a test run:
cat skycomponents/skymesh.h | sed ’s/include <Q\([^>]*\)>/include <q\1.h>/;T;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/’ | diff - skycomponents/skymesh.h
22,24c22,24
< #include <qhash.h>
< #include <qlist.h>
< #include <qobject.h>
—
> #include <QHash>
> #include <QList>
> #include <QObject>
26c26
< #include <qpainter.h>
—
> #include <QPainter>
HTH ![]()
July 5, 2008 at 12:26 pm
Two suggestions:
1. If you still use Emacs, read this. This is uber-cool:
http://www.ae.iitm.ac.in/pipermail/ilugc/2008-January/039377.html
2. Also, GNU sed does support those POSIX style parenthesis grouping.