Skip to content
Snippets Groups Projects

slides: fix a few typos and other minor changes

+ 60
54
@@ -554,7 +554,7 @@ $ echo my name is Bond
```
But this does not
```bash
```
$ echo my name is O'Donnelly
```
@@ -563,7 +563,7 @@ Why? And how can this be fixed?
Quoting - Examples 2
--------------------
The important difference betweenn `''` and `""` is that the latter allow
The important difference between `''` and `""` is that the latter allow
_expansions_ to occur (because `$` retains its special status):
```bash
@@ -662,10 +662,14 @@ Brace Expansion - Examples
```bash
$ echo {1..100} # e.g. in loops (see below)
$ echo {a..j} # works on chars
$ echo {10..1} # works in reverse
# Create a project tree (note nesting)
$ mkdir -p myproject/{src,doc/{mail,ref},data}
$ echo {a..j} # works on chars
$ echo {10..1} # works in reverse
# Create a project tree with nested expansions.
$ mkdir -p my_project/{src,doc/{mail,ref},data}
# Multiple expansions at the same level generate all possible combinations:
$ echo {A..D}{1..3}
```
Tilde Expansion
@@ -685,14 +689,14 @@ them because they're mostly relevant for interactive use.
Parameter Expansion
-------------------
A `$` followed by a parameter name is replaced by the parameter's value
A `$` followed by a parameter name is replaced by the parameter's value:
```bash
$ place=Rovaniemi
$ echo $place
Rovaniemi
$ echo "I'm off to $place"
I'm off to Rovaniemi
# -> I'm off to Rovaniemi
```
There is **a lot** more to parameter expansion than this. We'll come back to it
@@ -706,11 +710,11 @@ expansion, `$((...))`.]
```bash
$ echo "Today is $(date -I)"
$ home_size=$(du -s ~) # may take some time
$ home_size=$(du -s ~) # may take some time to compute.
$ nb_files=$(ls | wc -l)
```
An older form uses _backticks_:
An older form for command substitution uses _backticks_:
```bash
$ echo "it is now `date`"
@@ -732,16 +736,17 @@ $ a=2; b=3; echo $a*$b
This does:
```bash
$ a=2; b=3; echo $((a*b)) # no $ needed
$ a=2; b=3; echo $((a*b)) # Note: no $ needed
```
The expression between `$((...))` is evaluated using [shell
arithmetic](#shell-arithmetic) (more about this later)
arithmetic](#shell-arithmetic) - more about this later.
Process Substitution
--------------------
Replace a filename argument with the output of a command.
**Process Substitution `<(...)`** replaces a filename argument with the
output of a command.
Example: What species are common to two lists?
@@ -778,16 +783,16 @@ IFS
Word splitting uses the characters in the _internal field separator_ (by
default, `<space><tab><newline>`)^[Contrary to splitting into tokens, which uses
whitespace and metacharacters.] as word delimiters.
white space and metacharacters] as word delimiters.
This can be changed:
The `IFS` value can be changed:
```bash
$ line='gene_name,seq_len,mol_wt' # CSV-like
$ showa $line
$ IFS=','
$ showa $line
$ unset IFS # return to default
$ unset IFS # reset IFS to its default
```
If `$IFS` is null, no splitting is done. If unset, the above default is used.
@@ -868,7 +873,7 @@ $ ls
**Note**: redirection can be done from _within_ the script using `exec`:
```bash
exec <my_input.txt
exec < my_input.txt
# from now on, stdin comes from my_input.txt
```
@@ -877,13 +882,13 @@ Here Documents: `<<`
```bash
cat <<END
# Everything up to END goes to the input of cat
# Can be any word, not just END
# Everything up to END goes to the input of cat.
# The end word can be any word, not necessarily END.
# Quoting prevents expansion.
END
```
Useful to store some multiline output within the script - see `src/welcome.sh`.
Useful to generate multi-line outputs within a script - see `src/welcome.sh`.
Here Strings: `<<<`
------------
@@ -925,7 +930,7 @@ The main stages of input processing:
Project
=======
The Trouble with Fasta
The trouble with Fasta
----------------------
Here are some tasks that could be done on a Fasta file:
@@ -949,7 +954,7 @@ Why ?
* Unix shell tools (`sed`, `awk`, `grep`, etc.) are predominantly _line-oriented_
* Some bioinformatics formats are line-oriented (e.g. [GFF](#gff), [VCF](#vcf))
* Fasta is not (neither are GenBank, UniProt, ...)
* Converting FastA to some line-oriented format (e.g. CSV) would solve the problem^[The _format_ problem, that is - the rest can be left to `grep` and the like.]
* Converting Fasta to some line-oriented format (e.g. CSV) would solve the problem^[The _format_ problem, that is - the rest can be left to `grep` and the like.]
. . .
@@ -973,9 +978,9 @@ can run it.
```bash
#!/bin/bash
# the hash mark ('#') starts a comment
# The hash mark ('#') starts a comment.
echo "It works" # just to make sure
echo "It works" # just to make sure our script runs properly.
```
::: nonincremental
@@ -1144,7 +1149,7 @@ compound commands:
* conditionals (choice) - later
* groups (sequential flow) - not covered
They start and stop with a secific _keyword_ (`if...fi`, `{...}`, `while...done`, etc.)
They start and stop with a specific _keyword_ (`if...fi`, `{...}`, `while...done`, etc.)
Loops
-----
@@ -1156,7 +1161,7 @@ repeating commands, typically with minor modifications.
condition is met (`while`, `until`, `for ((...))`).
* This condition is expressed as a _test command_ (details later). The test
succeeds iff the command has 0 exit status.
succeeds if the command has 0 exit status.
`for` loop - 1st form
----------
@@ -1168,7 +1173,7 @@ for <name> in <words> ; do <commands> ; done
Expands `<words>`, and executes `<commands>`, binding `name` to each of the
resulting values in turn.
';' can be (and often is) replaced with newlines
`;`' can be (and often is) replaced with newlines.
`for` - Example 1
-----------------
@@ -1188,7 +1193,7 @@ done
Another typical case is with a sequence:
```bash
# first ten squares
# Compute square values of numbers from 1 to 10.
$ for n in {1..10} ; do echo $((n**2)) ; done
```
@@ -1203,9 +1208,9 @@ for ((<start-cmd>; <condition>; <iteration-cmd>)); do
done
```
1. Evaluate `<start-cmd>`
1. Evaluate `<condition>`; if true execute `<list>`, if not exit loop
1. Evaluate `<iteration-cmd>` and go back to 1.
1. Evaluate `<start-cmd>`.
2. Evaluate `<condition>`; if true execute `<list>`, if not exit loop.
3. Evaluate `<iteration-cmd>` and go back to 2.
Evaluations are done in shell arithmetic (again, more on this later).
@@ -1316,8 +1321,8 @@ age=42; age=forty-two # reassign
```
* **no spaces** around `=` !
* identifiers contain letters, digits, or underscores; they may not start by a
digit
* identifiers contain letters, digits, or underscores; they cannot start with a
digit.
* word splitting is disabled^[Except for arrays, but this outside the scope of this course]
Getting
@@ -1352,11 +1357,11 @@ Can you guess what the rule is?
Unset and Null
--------------
* A _null_ variable has the empty string for a value
* A _null_ variable has the empty string for a value.
* An _unset_ variable does not exist at all (and it's usually a mistake to try
to use its value^[Think of `NULL`, `null`, `nil`, `None`, or `Nothing` in your
favourite language])
* A variable can be deleted with `unset`
favourite language]).
* A variable can be deleted with `unset`.
```bash
$ place=Seoul # non-empty
@@ -1400,7 +1405,7 @@ $ PI=4096
bash: PI: readonly variable
```
Readonly variables can't be `unset`.
Read-only variables can't be `unset`.
Type
----
@@ -1458,7 +1463,7 @@ Now we've reinvented `cut -c1` \smiley{}
------
Now that we have the first character of each line, we need to
[test](#conditionals) if it's '`>`' or somethig else.
[test](#conditionals) if it's '`>`' or something else.
This is going to be a long excursion into testing.
@@ -1470,8 +1475,8 @@ enable the script to **choose what to do** between two or more possibilities.
The main conditional constructs are:
* `if` - yes-or-no decisions (possibly nested), based on a _test command_
* `case` - multi-way decision, based on pattern matching
* `if` - yes-or-no decisions (possibly nested), based on a _test command_.
* `case` - multi-way decision, based on pattern matching.
`if`
----
@@ -1480,7 +1485,7 @@ The basic idea:
```bash
if <test-command> ; then
<statements> # iff test-command returns 0
<statements> # if test-command returns 0
fi
```
@@ -1500,7 +1505,7 @@ else
fi
```
* There can be 0 or more `elif` clauses
* There can be 0 or more `elif` clauses.
* There can be 0 or 1 `else` clause.
A shortcut
@@ -1530,11 +1535,11 @@ Test Commands
Test commands are the main ingredient of `if...then`
[conditionals](#conditionals) and `while/until` [loops](#loops). They can be:
* a _list_ - the test succeeds iff the list itself succeeds (returns 0)
* a _list_ - the test succeeds iff the list itself succeeds (returns 0).
* a _conditional expression_ between `[[` and `]]` - the test succeeds if the expression is true;
the expression involves _strings_ (including filenames)^[An older form for conditional expression used `[...]` or `test`.]
the expression involves _strings_ (including filenames)^[An older form for conditional expression used `[...]` or `test`.].
* an _arithmetic expression_ between `((` and `))` - the test succeeds iff the expression is
**nonzero**^[There is actually a reason for this.]
**nonzero**^[There is actually a reason for this].
@@ -1576,18 +1581,18 @@ Many properties can be tested in this way (see next slide).
------
### A few file property test opertors
### A few file property test operators
operator true if
------- --------
`-d` file is a directory
`-f` file exists and is a regular file (e.g., not a dir)
`-r` file is readable
`-w` file is writeable
`-w` file is writable
`-x` file is executable
There are also a few file _comparison_ operators, such as `f1 -nt f2` which is
true iff `f1` is newer than `f2`. Obviously, they expect _two_ arguments.
true if `f1` is newer than `f2`. Obviously, they expect _two_ arguments.
------
@@ -2015,7 +2020,7 @@ Looping over Arguments
We know about `$1`, `$2`, etc., but what if the number of arguments isn't known?
* `"$@"` expands to all arguents, one word each.
* `"$@"` expands to all arguments, one word each.
(There are other ways to access all arguments, but `"$@"` is the most useful
here. See `../src/showpp.sh`)
@@ -2052,6 +2057,7 @@ We _could_ do something like
if [[ "$1" == '-h' ]] ; then ...
elif [[ "$1" == '-s' ]] ; then ...
elif [[ "$1" == '-t' ]] ; then ...
fi
```
But there is a better way:
@@ -2059,9 +2065,9 @@ But there is a better way:
`case`
-----
The `case`^[Very much like `switch` in C/C++/Java/Perl, or `case` in Ruby. Not
found in Python.] statement is like a multi-way `if`. Basically, it looks like
this:
The `case`^[Very much like `switch` in C/C++/Java/Perl, `case` in Ruby, or
`match-case` in Python.] statement is like a multi-way `if`. Basically, it
looks like this:
```bash
case <word> in
@@ -2119,7 +2125,7 @@ Conclusion
* We have seen how the shell operates, including tokenizing, parsing, the
various forms of expansions, conditionals and arithmetic.
* We have used this knowledge (and more) to write a script that converts FastA
* We have used this knowledge (and more) to write a script that converts Fasta
to CSV. It's not efficient, but it's easy to understand.
* You should now be able to start writing your own scripts.
@@ -2311,4 +2317,4 @@ References
* The [Bash website](https://www.gnu.org/software/bash/) and especially the [Bash Manual](http://www.gnu.org/software/bash/manual)
* [Advanced Bash Scripting Guide](ftp://ftp.wayne.edu/ldp/en/abs-guide/abs-guide.pdf)
* The [Bash Cheat Sheet](https://devhints.io/bash)
* The [Bash Programming Reference](https://gitlab.isb-sib.ch/tjunier/bash-prog-cheat) is another cheatsheet, more specialized towards programming.
* The [Bash Programming Reference](https://gitlab.isb-sib.ch/tjunier/bash-prog-cheat) is another cheat-sheet, more specialized towards programming.
Loading