 ## –ù–Α―à–Η –Ω–Α―Ä―²–Ϋ–Β―Ä―΄

–ö–Ϋ–Η–≥–Η –Ω–Ψ Linux (―¹ –Ψ―²–Ζ―΄–≤–Α–Φ–Η ―΅–Η―²–Α―²–Β–Μ–Β–Ι)

–ë–Η–±–Μ–Η–Ψ―²–Β–Κ–Α ―¹–Α–Ι―²–Α rus-linux.net

# 10.3. Operations on variables

## 10.3.1. Arithmetic on variables

We discussed this already in Section 3.4.6.

## 10.3.2. Length of a variable

Using the \${#`VAR`} syntax will calculate the number of characters in a variable. If `VAR` is "*" or "@", this value is substituted with the number of positional parameters or number of elements in an array in general. This is demonstrated in the example below:

 ``` `[bob in ~]` echo `\$SHELL` /bin/bash `[bob in ~]` echo `\${#SHELL}` 9 `[bob in ~]` `ARRAY`=`(one two three)` `[bob in ~]` echo `\${#ARRAY}` 3 ```

## 10.3.3. Transformations of variables

### 10.3.3.1. Substitution

\${`VAR`:-`WORD`}

If `VAR` is not defined or null, the expansion of `WORD` is substituted; otherwise the value of `VAR` is substituted:

 ``` `[bob in ~]` echo `\${TEST:-test}` test `[bob in ~]` echo `\$TEST` `[bob in ~]` export `TEST`=`a_string` `[bob in ~]` echo `\${TEST:-test}` a_string `[bob in ~]` echo `\${TEST2:-\$TEST}` a_string ```

This form is often used in conditional tests, for instance in this one:

 ``` `[ -z "\${COLUMNS:-}" ]` && `COLUMNS`=`80` ```

It is a shorter notation for

 ``` if `[ -z "\${COLUMNS:-}" ]`; then `COLUMNS`=`80` fi ```

If the hyphen (-) is replaced with the equal sign (=), the value is assigned to the parameter if it does not exist:

 ``` `[bob in ~]` echo `\$TEST2` `[bob in ~]` echo `\${TEST2:=\$TEST}` a_string `[bob in ~]` echo `\$TEST2` a_string ```

The following syntax tests the existence of a variable. If it is not set, the expansion of `WORD` is printed to standard out and non-interactive shells quit. A demonstration:

 ``` `[bob in ~]` cat `vartest.sh` #!/bin/bash # This script tests whether a variable is set. If not, # it exits printing a message. echo \${TESTVAR:?"There's so much I still wanted to do..."} echo "TESTVAR is set, we can proceed." `[bob in testdir]` ./vartest.sh ./vartest.sh: line 6: TESTVAR: There's so much I still wanted to do... `[bob in testdir]` export `TESTVAR`=`present` `[bob in testdir]` ./vartest.sh present TESTVAR is set, we can proceed. ```

Using "+" instead of the exclamation mark sets the variable to the expansion of `WORD`; if it does not exist, nothing happens.

### 10.3.3.2. Removing substrings

To strip a number of characters, equal to `OFFSET`, from a variable, use this syntax:

\${`VAR`:`OFFSET`:`LENGTH`}

The `LENGTH` parameter defines how many characters to keep, starting from the first character after the offset point. If `LENGTH` is omitted, the remainder of the variable content is taken:

 ``` `[bob in ~]` export `STRING`=`"thisisaverylongname"` `[bob in ~]` echo `\${STRING:4}` isaverylongname `[bob in ~]` echo `\${STRING:6:5}` avery ```

\${`VAR`#`WORD`}

and

\${`VAR`##`WORD`}

These constructs are used for deleting the pattern matching the expansion of `WORD` in `VAR`. `WORD` is expanded to produce a pattern just as in file name expansion. If the pattern matches the beginning of the expanded value of `VAR`, then the result of the expansion is the expanded value of `VAR` with the shortest matching pattern ("#") or the longest matching pattern (indicated with "##").

If `VAR` is `*` or `@`, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list.

If `VAR` is an array variable subscribed with "*" or "@", the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. This is shown in the examples below:

 ``` `[bob in ~]` echo `\${ARRAY[*]}` one two one three one four `[bob in ~]` echo `\${ARRAY[*]#one}` two three four `[bob in ~]` echo `\${ARRAY[*]#t}` one wo one hree one four `[bob in ~]` echo `\${ARRAY[*]#t*}` one wo one hree one four `[bob in ~]` echo `\${ARRAY[*]##t*}` one one one four ```

The opposite effect is obtained using "%" and "%%", as in this example below. `WORD` should match a trailing portion of string:

 ``` `[bob in ~]` echo `\$STRING` thisisaverylongname `[bob in ~]` echo `\${STRING%name}` thisisaverylong ```

### 10.3.3.3. Replacing parts of variable names

This is done using the

\${`VAR`/`PATTERN`/`STRING`}

or

\${`VAR`//`PATTERN`/`STRING`}

syntax. The first form replaces only the first match, the second replaces all matches of `PATTERN` with `STRING`:

 ``` `[bob in ~]` echo `\${STRING/name/string}` thisisaverylongstring ```