Oftentimes one needs to copy or move several files at once. This can be done by providing a list of individual filenames, or specifying a naming pattern using wildcards.
For this exercise, you can test the commands in the shell-lesson-data/data directory.
In the example below, what does cp do when given several filenames and a directory name?
$ mkdir backup
$ cp amino-acids.txt animals.txt backup/
In the example below, what does cp do when given three or more file names?
$ ls -F
amino-acids.txt animals.txt backup/ elements/ morse.txt pdb/
planets.txt salmon.txt sunspot.txt
$ cp amino-acids.txt animals.txt morse.txt
* is a wildcard, which matches zero or more characters.
Let’s consider the shell-lesson-data/alkanes directory:
*.pdb matches ethane.pdb, propane.pdb, and every
file that ends with ‘.pdb’. On the other hand, p*.pdb only matches
pentane.pdb and propane.pdb, because the ‘p’ at the front only
matches filenames that begin with the letter ‘p’.
? is also a wildcard, but it matches exactly one character.
So ?ethane.pdb would match methane.pdb whereas
*ethane.pdb matches both ethane.pdb, and methane.pdb.
Wildcards can be used in combination with each other
e.g. ???ane.pdb matches three characters followed by ane.pdb,
giving cubane.pdb ethane.pdb octane.pdb.
When the shell sees a wildcard, it expands the wildcard to create a list of matching filenames before running the command that was asked for. As an exception, if a wildcard expression does not match any file, Bash will pass the expression as an argument to the command as it is. {: .callout}
When run in the alkanes directory, which ls command(s) will
produce this output?
ethane.pdb methane.pdb
ls *t*ane.pdbls *t?ne.*ls *t??ne.pdbls ethane.*You’re starting a new experiment and would like to duplicate the directory structure from your previous experiment so you can add new data.
Assume that the previous experiment is in a folder called ‘2016-05-18’,
which contains a data folder that in turn contains folders named raw and
processed that contain data files. The goal is to copy the folder structure
of the 2016-05-18-data folder into a folder called 2016-05-20
so that your final directory structure looks like this:
2016-05-20/
└── data
├── processed
└── raw
Which of the following set of commands would achieve this objective? What would the other commands do?
$ mkdir 2016-05-20
$ mkdir 2016-05-20/data
$ mkdir 2016-05-20/data/processed
$ mkdir 2016-05-20/data/raw
$ mkdir 2016-05-20
$ cd 2016-05-20
$ mkdir data
$ cd data
$ mkdir raw processed
$ mkdir 2016-05-20/data/raw
$ mkdir 2016-05-20/data/processed
$ mkdir -p 2016-05-20/data/raw
$ mkdir -p 2016-05-20/data/processed
$ mkdir 2016-05-20
$ cd 2016-05-20
$ mkdir data
$ mkdir raw processed
Bash also supports brace expansion whereby multiple paths can be created with a single expression. For example to reproduce the folder structure only a single command is needed:
$ mkdir -p 2016-05-20/data/{raw, processed}
As bash expands it to:
$ mkdir -p 2016-05-20/data/raw 2016-05-20/data/processed
This can be useful when creating nested file structures or when creating multiple directories quickly.