c. Exercises I
Variables in Loops
This exercise refers to the shell-lesson-data/molecules
directory.
ls
gives the following output:
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
What is the output of the following code?
$ for datafile in *.pdb
do
ls *.pdb
done
Now, what is the output of the following code?
$ for datafile in *.pdb
do
ls $datafile
done
Why do these two loops give different outputs?
Solution
The first code block gives the same output on each iteration through
the loop. Bash expands the wildcard *.pdb
within the loop body (as well as
before the loop starts) to match all files ending in .pdb
and then lists them using ls
. The expanded loop would look like this:
$ for datafile in cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
do
ls cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
done
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
cubane.pdb ethane.pdb methane.pdb octane.pdb pentane.pdb propane.pdb
The second code block lists a different file on each loop iteration.
The value of the datafile
variable is evaluated using $datafile
,
and then listed using ls
.
cubane.pdb
ethane.pdb
methane.pdb
octane.pdb
pentane.pdb
propane.pdb
Limiting Sets of Files
What would be the output of running the following loop in the
shell-lesson-data/molecules
directory?
$ for filename in c*
do
ls $filename
done
- No files are listed.
- All files are listed.
- Only
cubane.pdb
, octane.pdb
and pentane.pdb
are listed. - Only
cubane.pdb
is listed.
Solution
4 is the correct answer. *
matches zero or more characters, so any file name starting with
the letter c, followed by zero or more other characters will be matched.
How would the output differ from using this command instead?
$ for filename in *c*
do
ls $filename
done
- The same files would be listed.
- All the files are listed this time.
- No files are listed this time.
- The files
cubane.pdb
and octane.pdb
will be listed. - Only the file
octane.pdb
will be listed.
Solution
4 is the correct answer. *
matches zero or more characters, so a file name with zero or more
characters before a letter c and zero or more characters after the letter c will be matched.