Saturday, February 13, 2010

Mass rename/move in bash

for i in *.HTM;
do mv $i `basename $i HTM`html;

There are a number of components to this mini hack.

First is the for loop. This is pretty straightforward if you know bash path regular expressions. The regex *.HTM is expanded to make a list of all files in the current directory that end in HTM. Note that this is case sensitive in Linux. Then we itereate over this list.
The meat of the loop is in the do part. We mv the original name to a name constructed by the following expression:

`basename $i HTM`html

The backticks means run the command in the backticks and use the output.

basename does two things here. It strips away the directory part of the path. In this case, there is none. The important part is the HTM argument to basename which means that we want to strip away the HTM suffix. For example:

basename readme.txt txt

will return


Note the period is kept.
Then doing this:

`basename $i HTM`html

Will return the basenemt concatenated with html. This is how we do string concatenation in bash. See previous article: String concatenation in bash.

Put that all together, we are able to do a mass rename/move in bash. Note that if we want to do more complicated pattern matching and renaming, we probably would have to do it in Python or Perl.

Thursday, February 4, 2010

sed: find and replace in place

To replace in place means to change the original file with the substitutions. (Contrary to the default behavior of sed which is to print to standard out.)

It's simple:

sed -i 's/sad/happy/g' filetochange.txt

Wednesday, February 3, 2010

A click from the Office of the President

I was going through the logs for Little Tech Tips recently and found this:


Haven't they heard?

Of course it was kind of cool that someone at the Executive Office of the President uses vim. :)

C++ Tidbit: The Copy Constructor

The copy constructor is a constructor that takes a single paramter that is:
1. Usually const
2. A reference to an object of the same type. (Meaning the class that is being defined.)

The copy constructor is important in C++ for a number of reasons:

- It is used to initialize an object from another object of the same type. Everything other use of the copy constructor stems from this use.
- The copy constructor is used to copy an object to pass it as an argument to a function. That is, when an object is passed by value, the copy constructor is called.
- And of course, it is used to copy an object to return it from a function.
- It is also used initialize elements of a sequential container

The important thing to note is that if we don't define a copy constructor, the compiler will define one for us. The new object is initialized by copying the members of the old object one by one. For some cases this is actually what we want.