Bash manipulation on sequences.

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
0001
0002
0003

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
1
2
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.

2 thoughts on “Bash manipulation on sequences.”

  1. That’s pretty cool. I hadn’t heard of seq. I’ll play with that.

    I always found tcsh filename modifiers very useful. simply :r :e :h :t for root, extension, head and tail respectively. But bash is overall a better shell so I switched, but then found the bash filename modifiers suck. So I made some bash functions to emulate the tcsh filename modifiers as close as possible. You may be interested. They can be chained too like tcsh.

    See here: my answer here: http://stackoverflow.com/questions/5147161/how-can-i-chain-together-filename-modifiers-in-a-bash-shell

  2. Oh yeah I miss those. So easy to remember. The bash modifiers are murderous (hard to remember), I agree. Maybe that’s cause I started on tcsh myself.

    Aside from using the arcane posix syntax , you can always use the utililties `basename’ which I found an example of here

Leave a Reply

Your email address will not be published. Required fields are marked *


*