The Orient Express

June 21, 2007

Orient express

Today Nadia and I took her parents on a day-trip to Folkstone on the Orient Express. We left Victoria at about 11:30 and had a delicious three course lunch on the way down. The main course, in particular, was fantastic.

The train in itself was an experience. It consisted exclusively of British Pullman carriages; ours was the Ibis, built in 1925. We had our own compartment, and people in white uniforms falling over themselves to make sure we had a comfortable journey.

Even the toilet was spacious, and came complete with a huge marble sink and naked lady mosaic flooring. I also liked that it had honest-to-god coat-hangers so you could hang your coat up properly whilst riding the porcelain bus. None of those pert knobs on the wall that leaves your jacket a funny shape afterwards. Oh, no.

As we arrived at Folkstone Harbour Band a four-piece band started playing 1920’s music. Well, it sounded like 1920’s music to me, at least. They were jolly, and pretty good, and added a great atmosphere.

We were taken by bus up to Grand and Metropole hotels, where we spent a good 80 minutes stretching our legs trotting around the grounds and lounging in the bar. Nadia and I also had a good laugh at a Japanese woman with one of the weirdest head-garments I’ve ever seen. It looked like she’d super-glued half a surf-board to her forehead. It was hilarious. I wish I managed to get a picture of it, but I was laughing too hard.

We left an hour late from Folkstone, but the driver managed to rein in about three quarters of that, making our homeward trip a little bouncier than I’d liked. It meant that if we filled our tea-cups more than one third up, they would spill if we didn’t hold on to them all the time. Other than that, the sandwiches, scones, clotted cream, jam, and cakes were all wonderful.

So, in my previous hack I showed how to rename lots of files with little effort. Let’s remind ourselves how the one-liner looks:

for f in *.doc ; do mv $f ${f%.doc}.txt ; done

Imagine that you haven’t done that kind of transformation a thousand times and so feel a bit apprehensive about diving right in. The standard way to get around that is to pre-pend the command with echo:

for f in *.doc ; do echo mv $f ${f%.doc}.txt ; done

Now, instead of performing a lot of renames, your loop will just print out the commands it would do if the echo was not there. When you’ve looked over the output and satisfied that it will do what you want, you have to options. You can either edit the command to remove the echo, or you can pipe the result to sh -; the latter being my favourite:

for f in *.doc ; do echo mv $f ${f%.doc}.txt ; done | sh -

The pipe, for those who haven’t encountered it, means that the output of the command to the left of it is used as input for the command to the right. The sh command is just a shell[1], and invoking it with the argument ‘-’ means that it should read commands from its standard input and execute each line. Simple!

[1] - similar to the one you’re typing these commands into; on your system, it’s probably an alias for bash or zsh.

Best..retort..evar!

June 14, 2007

> > As the great Alexi Sayle said: “Pedantic, I ?”

> Um, that would be _Alexei_ Sayle.

From a mailing list.

To be honest, this exchange is so good that you’d almost think it has been choreographed. It reminds me of the following quote from irc over at bash.org.

Peter Corlett in London.pm:

It’s usually cheaper to send it to yourself via Citylink for destruction,
and then again via Parcelforce for disposal.

Oh how I agree.

I was astounded to find out a couple of days ago that one of my colleagues was not aware of shell parameter expansion. He’d been confronted with the following problem:

Given a directory full of files, write a shell one-liner to rename all the ones ending in .doc such that they now end in .txt.

I almost choked on my drink as I heard suggestions involving Perl. No need to complicate things. Here’s how to solve the task using parameter expansion (both Bash and Zsh certainly have these):

for f in *.doc ; do mv $f ${f%.doc}.txt ; done

Now I know that my previously mentioned colleague won’t need the following explanation (he’s already dived into the Bash man page by now, I suspect), but I’m feeling wordy for a change. Here’s the above line with white space added for readability:

for f in *.doc ; do
    mv $f ${f%.doc}.txt
done

On the first line we use a shell glob (the *) to select all the files in the current directory that ends in .doc. For each iteration of the for loop, the variable f contains the name of one of those files. The third line just says that we’re done with the looping, so all the really interesting bits are happening in the second line.

That line says: rename[1] the file named $f (in shell programming we put a $ in front of the variable name when it can be confused with a literal string) to the result of the following expression: ${f%.doc}.txt. Of that ${f%.doc} is the parameter expansion part. From the zsh man page:

${name%pattern}
${name%%pattern}

If the pattern matches the end of the value of name, then substitute the value of name with the matched portion deleted; otherwise, just substitute the value of name. In the first form, the smallest matching pattern is preferred; in the second form, the largest matching pattern is preferred.

What that means is that if the string in the variable f contains .doc at the end of it (which we know that it does) strip it off. This will be the case for all the files, since our for loop only iterates over files with this ending. The dot over the i is that we simply append .txt.

There are loads of other parameter expansion tricks you can do, including the following, which should feel familiar to Perl people: ${f:gs/foo/bar/}—substitute with the content of the variable f, but with the string “foo” replaced by “bar” everywhere it occurs in f.

Enough from me. Dive into the Bash/Zsh man page already!

[1] — on Unix a rename is just a move[2] to a new name.
[2] — Unix geeks are lazy typists, hence “move” was shortened to “mv”.

Pop Quiz

June 11, 2007

I’ve just been to the gym. As I gathered all my things and prepared to leave the changing rooms a tall lanky guy arrived and dropped his open gym bag on the floor. And, here’s the thing, a huge tub of Vaseline fell out.

Honestly, why would anyone keep a tub of Vaseline in their gym bag? I’m sure keeping the machines well-greased is the responsibility of the people who run the gym, so what use could it possibly be? Answers in the comments please! (Oh, and keep it tidy please.)

Oops. I had somehow disallowed commenting on this post. Fixed now. Comment away!

Can of Worms

June 5, 2007

can-of-worms.jpg

You know the feeling: you’re at your desk, planet-sized brain poring over some code through your beady browns. Then out of the blue somebody arrives with a can of worms, and there can be no mistake: it’s got your name written on it. It’s yours.

This happened to me at work today. It wasn’t your regular baked-bean tin either. No, sir! It was a large green plastic container. With a carrying handle. Subsidised by the council, even. And not to forget: my name on the shipping label.

Normally I’d kicked the bucket at this point, but today it was a pleasant surprise. I did not expect my new wormery until tomorrow.

It’s a wonderful thing. I think. I’ll feed it leftover food, cardboard, egg-shells, dust-rabbits, and the contents of my Dyson; in return, the little crawlies inside will produce excellent compost for my plants.

(Pictures of the actual worms in question over here.)