I rarely use bash besides the basics: I could use a for loop even if woken up at night, but my knowledge of the language doesn’t go much further. Hence instead of trying to memorize all the {}%$ magic, having a few versatile commands in my toolbox comes handy.
Recently I faced the task of renaming a set of files {foo 02.jpg, …, foo 74.jpg} to {foo 06.jpg, …, foo 78.jpg}, while keeping the order. My approach contained nothing extraordinary:
#!/bin/bash
for i in `seq 74 2`
do
printf -v oldname "foo %02d.jpg" $i
printf -v newname "foo %02d.jpg" $(echo "$i+4" | bc)
mv "$oldname" "$newname"
done
Yet there were some educational points in it:
- One loops a variable
xover the lines of a stringvaluesbyfor x in values; do something; something_else; done. seq a bsimply prints out the integers fromatob, inclusive, regardless of which is larger.- Variable
xis assigned a value byx=foobar, where there must be no spaces around the equation sign.The value ofxcan then be referred to by$x. - Renaming a set of files to a similar name but later in the alphabet must be done in reverse order.
- Bash has a built-in
printfthat seems to work as in C: first the string to be printed with format specifiers like%02d, followed by the arguments whose values are used according to the format specifiers. - With the
-voption ofprintf, you can save the output into a variable. - One can use
$( )for executing a command and having bash treat the output as the source code. (It’s the same as using backticks, as aroundseq 74 2, but allows nesting and is clearer. Kinda likeevalin other languages, like JavaScript.) Not shown here, but it even works in quotation marks, e.g."$(echo hey yo)"is like writing"hey yo". Note that the trailing newline is deleted. bcis a calculator that reads from the input and outputs nothing but the result on a single line.- Don’t forget the quotes around arguments with spaces, like with
mvabove.
One minute of further bash tips are provided by Julia Evans [here].