I’m going to come at you today with a very common situation. Renaming a series of files, bash and GNU utils style. This applies to something as trivial as importing my camera photos which typically gives me a bunch of files named IMG_2042.JPG, IMG_2043.JPG, IMG_2044.JPG and so on. I’m here to show you how to deal with that.
We’re gonna tackle this ground up. Firstly, I need a way to increment a number. seq is our tool.
seq -f %04g 1 3
Sexy huh? We’ve already have a major building block right here. Let’s dissect this quickly. The ‘-f’ tells seq that we want a specially formatted list of numbers. In our case, zero padded numbers, at least 4 wide (%04). The letter ‘g’ gets replaced the current number in the following range (1 thru 3 in our case). If you don’t have padded numbers you can omit the use of ‘-f %04g’ altogether. The last two arguments are the range to start and end.
seq 1 3
Sweet, now we have way of representing pretty much any sequence of numbers, thanks seq! Now let’s tackle looping over this sequence of numbers and use them for renaming using a simple ‘for’ loop. In our case below the letter ‘n’ will get the results of the seq command.
for n in $(seq -f %04g 2042 2044) ; do mv IMG_$n.JPG utah.$n.jpg ; done
`IMG_2042.JPG' -> `utah.2042.jpg'
`IMG_2043.JPG' -> `utah.2043.jpg'
`IMG_2044.JPG' -> `utah.2044.jpg'
That one-liner is so unbelievably flexible (replace `mv’ with `cp’ or `ln’ for instance) it will probably be your number one oft used idiom while working with bash in production. As a matter of fact, pretty much every thing I do is looping over a list of things – yum, sounds lispy.
I’ve always found this to be a great (re)read. In the beginning was the command line. It’s a zip archive, with an ol’ fashioned text file for you to read authored by Neal Stephenson.