eolas/Programming_Languages/Shell/Expansions_and_substitutions.md

97 lines
2.5 KiB
Markdown
Raw Normal View History

2023-01-31 13:55:42 +00:00
---
categories:
- Programming Languages
tags:
- shell
---
# Expansions and substitutions
Bash is weird in that parentheses, braces and brackets are used not just as markers for different code blocks but as the designators of commands in their own right. The type of bracket you use effects how your input is interpreted.
Below are the main forms of expansion and substitution:
| Representation | Name |
| -------------- | -------------------- |
| `~` . | Tilde expansion |
2023-02-03 14:51:52 +00:00
| `{..}` | Brace expansion |
2023-01-31 13:55:42 +00:00
| `${...}` | Parameter expansion |
| `$(...)` | Command substitution |
| `$((...))` | Arithmetic expansion |
2023-02-03 14:51:52 +00:00
## Brace expansion: `{..}`
2023-01-31 13:55:42 +00:00
Brace expansion is for changing a smaller part of a greater whole programmatically. This is best understood by looking at examples:
```
echo c{a,o,u}t
cat cot cut
```
```
echo /tmp/{1..3}/file.txt
/tmp/1/file.txt /tmp/2/file.txt /tmp/3/file.txt
```
```
echo {1..5}
1 2 3 4 5
echo {5..1}
5 4 3 2 1
echo {a...c}
a b c
```
2023-02-03 14:51:52 +00:00
We can also set sequences. If we wanted to count to twenty in intervals of two
2023-01-31 13:55:42 +00:00
```
echo {1..20..2}
1 3 5 7 9 11 13 15 17 19
```
> Note that we type _two_ dots **not** an elipsis
2023-02-03 14:51:52 +00:00
### Example use case
2023-01-31 13:55:42 +00:00
2023-02-03 14:51:52 +00:00
We might use brace expansion to generate sequential file names using a pre-defined naming scheme, eg.
2023-01-31 13:55:42 +00:00
```
touch file_{01..12}{a..d}
ls
file_01a
file_01b
file_01c
file_01d
file_02a
file_02b
...
file_12d
2023-02-03 14:51:52 +00:00
```
The syntax here basically means: for each of the elements in the first list, run the second list against them.
## Parameter expansion: `${...}`
We use most frequently for returning the value of stored [variables](/Programming_Languages/Shell/Variables_and_data_types.md). Techically we do not have to use the braces, we can retrieve with just `$var` however it's better to use them to minimise interpretation fuck-ups which happen a lot.
When the braces are used, this allows us to transform the values before they are returned such as only returning from the 6th character: `${var:6}`.
2023-01-31 13:55:42 +00:00
2023-02-03 14:51:52 +00:00
## Command substition: `$(...)`
2023-01-31 13:55:42 +00:00
2023-02-03 14:51:52 +00:00
Command substitution (circle-brackets) allows us to put the output of one command inside another. Bash runs the bracketed command in a [sub-shell](/Programming_Languages/Shell/Shell_sessions.md) and then returns it to the main user shell.
For example:
```bash
echo "The current directory is $(pwd)."
2023-01-31 13:55:42 +00:00
```
2023-02-03 14:51:52 +00:00
## Arithemtic expansion: `$((...))`
We use arithmetic expansion when we want to calculate numerical values
See [Working with numbers in Bash](/Programming_Languages/Shell/Working_with_numbers_in_Bash.md) for more.