Creating a Loop

Loop are meant to perform the same actions multiple times. For example, changing the name of many different files.

Note

When a command is not finished (for example when we are still editing a loop), the prompt changes from $ to >

The FOR loop

One of the most basic loops is the so called “for loop”, because it begins with the instruction for. It is a loop based on the iteration over something, and it means execute the following for a certain number of iterations.

It is composed of the following essential blocks:

  • for instruction followed by an expression (or a list) indicating the number of iterations

  • do command, indicating where the series of commands to be executed for n iteration begins

  • the list of instructions/commands to be executed in a loop

  • done command, indicating where the loop ends

Using the for loop to change file extension

We can look at a concrete case, which might happen frequently: we want to change the name of many files, maybe change their extension. A typical example is the index of a bam file called alignment.bam , which some software create as alignment.bam.bai and some other software instead create as alignment.bai. We have created the index with one application, but now we want to use it with another which needs the other kind of file name.

Let’s start by creating some dummy files, purely for the exercise:

$ touch file1.bam.bai file2.bam.bai file3.bam.bai file4.bam.bai
$ ls *.bai
file1.bam.bai  file2.bam.bai  file3.bam.bai  file4.bam.bai

We now want to use the string removal trick, to remove bam.bai and attach .bai effectively removing bam. from the name. The command we know would be

$ filename="file1.bam.bai"
$ echo "${filename%bam.bai}bai"
file1.bai

However, we want to do this for all files, and we will use the command mv to rename them

Warning

Before performing potentially dangerous loops, i.e. changing the name of many files, it is always good to run the loop using the command echo instead of the command mv to make sure we print what should happen at screen before making it happen

We can therefore prepare the loop as follows:

$ for file in `ls *.bai`
> do
> mv $file "${file%bam.bai}bai"
> done

$ ls
file1.bai  file2.bai  file3.bai  file4.bai