Bash in 5 mins
Suppose you wanna iterate over a number of things, such as the sequence 1..10, or the directory listing (the output of the ls
command), or lines in a file.
To do this in Bash, use the following syntax (where WORD
and LIST
are according to the definitions in the Bash man page).
for k in WORDs ; do LIST; done
You have options on how to specify WORDs
, including expansions, substitutions, or writing them out by hand.
Let’s start with expansions. You can use a brace expansion, which are evaluated before any commands are executed
$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
So, the following statements are equivelant:
for k in {1..10}; do echo $k; done
for k in 1 2 3 4 5 6 7 8 9 10; do echo $k; done
Alternatively, use the output of the seq
command with with command substitution, where the value of the command is substituted in place of the command
$ seq 10
1
2
3
4
5
6
7
8
9
10
$ echo $(seq 10)
1 2 3 4 5 6 7 8 9 10
So we can then say, again equivelant to the above,
for k in $(seq 10); do echo $k; done
Let’s take another example, iterating over the directory listing. It can be done with command substitution this way
for k in $(ls); do echo $k; done
and can be done with a wildcard expansion (another kind of expansion) this way
for k in *; do echo $k; done
Another substitution is process substitution, which enables referring to the output of a command as a filename. So for example, if the syntax of the command is
$ cat FILE
Where file contains a list of numbers obtained using redirection with seq 10 > FILE
. You can use
$ cat <(seq 10)
The above is redundant since we can just write seq 10
to show the result. Another one, let’s read a file line by line and echo it to the screen
while read line; do echo $line; done < <(seq 10)
what happens when you echo a file name?
$ echo <(seq 10)
/proc/self/fd/63
Here is a better usage of process substitution, since its asynchronous, lets use it with the curl command
$ grep bash <(curl https://azizcodes.github.io)
Here is another quick overview.