Usually when I write a shell script for a specific task, I just make a list of files like so:
#/bin/sh
read -d '' imagefiles <<EOF
./01/IMG0000.jpg
./01/IMG0001.jpg
./01/IMG0002.jpg
./01/IMG0003.jpg
./01/IMG0004.jpg
./01/IMG0005.jpg
./01/IMG0006.jpg
./01/IMG0007.jpg
(a whole bunch of files down to ./10/IMG0102.jpg)
EOF
for i in $imagefiles
for j in range(len(commands))
do
mv $i ./$j.jpg
done
done
In this instance I wanted to be able to iterate over the output of seq
but following Gilles's suggestion simply wrote that part out of it out as Python (yeah I know that as it is it would execute each command j times, leading to about 100000 executions). Earlier on in the day I was renaming 736 files in sequence, but now I'm renaming 1000-odd files. I'm sure there's a better way to do that (please don't hesitate to tell me), but it would still be nice to know how to iterate over the list of commands and some other iterable.
Best Answer
Ok, so you want to zip two iterables, or in other words you want a single loop, iterating over a bunch of strings, with an additional counter. It's quite easy to implement a counter.
Note that this only works if none of the elements that you're iterating over contains any whitespace (nor globbing characters). If you have items separated by newlines, turn off globbing and split only on newlines.
If you only need to iterate over the data once, loop around
read
(see Why iswhile IFS= read
used so often, instead ofIFS=; while read..
? for more explanations).If you're using a shell that has arrays (bash, ksh or zsh), store the elements in an array. In zsh, either run
setopt ksh_arrays
to number array elements from 0, or adapt the code for array element numbering starting at 1.