diff options
| author | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2024-04-07 13:41:34 -0500 |
| commit | 754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch) | |
| tree | f1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/bash/shell-parameter-expansion.html | |
new repository
Diffstat (limited to 'devdocs/bash/shell-parameter-expansion.html')
| -rw-r--r-- | devdocs/bash/shell-parameter-expansion.html | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/devdocs/bash/shell-parameter-expansion.html b/devdocs/bash/shell-parameter-expansion.html new file mode 100644 index 00000000..d73dd536 --- /dev/null +++ b/devdocs/bash/shell-parameter-expansion.html @@ -0,0 +1,139 @@ +<h1 class="subsection">Shell Parameter Expansion</h1> <p>The ‘<samp>$</samp>’ character introduces parameter expansion, command substitution, or arithmetic expansion. The parameter name or symbol to be expanded may be enclosed in braces, which are optional but serve to protect the variable to be expanded from characters immediately following it which could be interpreted as part of the name. </p> <p>When braces are used, the matching ending brace is the first ‘<samp>}</samp>’ not escaped by a backslash or within a quoted string, and not within an embedded arithmetic expansion, command substitution, or parameter expansion. </p> <p>The basic form of parameter expansion is ${<var>parameter</var>}. The value of <var>parameter</var> is substituted. The <var>parameter</var> is a shell parameter as described above (see <a href="shell-parameters">Shell Parameters</a>) or an array reference (see <a href="arrays">Arrays</a>). The braces are required when <var>parameter</var> is a positional parameter with more than one digit, or when <var>parameter</var> is followed by a character that is not to be interpreted as part of its name. </p> <p>If the first character of <var>parameter</var> is an exclamation point (!), and <var>parameter</var> is not a nameref, it introduces a level of indirection. Bash uses the value formed by expanding the rest of <var>parameter</var> as the new <var>parameter</var>; this is then expanded and that value is used in the rest of the expansion, rather than the expansion of the original <var>parameter</var>. This is known as <code>indirect expansion</code>. The value is subject to tilde expansion, parameter expansion, command substitution, and arithmetic expansion. If <var>parameter</var> is a nameref, this expands to the name of the variable referenced by <var>parameter</var> instead of performing the complete indirect expansion. The exceptions to this are the expansions of ${!<var>prefix</var>*} and ${!<var>name</var>[@]} described below. The exclamation point must immediately follow the left brace in order to introduce indirection. </p> <p>In each of the cases below, <var>word</var> is subject to tilde expansion, parameter expansion, command substitution, and arithmetic expansion. </p> <p>When not performing substring expansion, using the form described below (e.g., ‘<samp>:-</samp>’), Bash tests for a parameter that is unset or null. Omitting the colon results in a test only for a parameter that is unset. Put another way, if the colon is included, the operator tests for both <var>parameter</var>’s existence and that its value is not null; if the colon is omitted, the operator tests only for existence. </p> <dl compact> <dt><span><code>${<var>parameter</var>:-<var>word</var>}</code></span></dt> <dd> +<p>If <var>parameter</var> is unset or null, the expansion of <var>word</var> is substituted. Otherwise, the value of <var>parameter</var> is substituted. </p> <div class="example"> <pre class="example">$ v=123 +$ echo ${v-unset} +123 +</pre> +</div> </dd> <dt><span><code>${<var>parameter</var>:=<var>word</var>}</code></span></dt> <dd> +<p>If <var>parameter</var> is unset or null, the expansion of <var>word</var> is assigned to <var>parameter</var>. The value of <var>parameter</var> is then substituted. Positional parameters and special parameters may not be assigned to in this way. </p> <div class="example"> <pre class="example">$ var= +$ : ${var:=DEFAULT} +$ echo $var +DEFAULT +</pre> +</div> </dd> <dt><span><code>${<var>parameter</var>:?<var>word</var>}</code></span></dt> <dd> +<p>If <var>parameter</var> is null or unset, the expansion of <var>word</var> (or a message to that effect if <var>word</var> is not present) is written to the standard error and the shell, if it is not interactive, exits. Otherwise, the value of <var>parameter</var> is substituted. </p> <div class="example"> <pre class="example">$ var= +$ : ${var:?var is unset or null} +bash: var: var is unset or null +</pre> +</div> </dd> <dt><span><code>${<var>parameter</var>:+<var>word</var>}</code></span></dt> <dd> +<p>If <var>parameter</var> is null or unset, nothing is substituted, otherwise the expansion of <var>word</var> is substituted. </p> <div class="example"> <pre class="example">$ var=123 +$ echo ${var:+var is set and not null} +var is set and not null +</pre> +</div> </dd> <dt><span><code>${<var>parameter</var>:<var>offset</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>:<var>offset</var>:<var>length</var>}</code></span></dt> <dd> +<p>This is referred to as Substring Expansion. It expands to up to <var>length</var> characters of the value of <var>parameter</var> starting at the character specified by <var>offset</var>. If <var>parameter</var> is ‘<samp>@</samp>’ or ‘<samp>*</samp>’, an indexed array subscripted by ‘<samp>@</samp>’ or ‘<samp>*</samp>’, or an associative array name, the results differ as described below. If <var>length</var> is omitted, it expands to the substring of the value of <var>parameter</var> starting at the character specified by <var>offset</var> and extending to the end of the value. <var>length</var> and <var>offset</var> are arithmetic expressions (see <a href="shell-arithmetic">Shell Arithmetic</a>). </p> <p>If <var>offset</var> evaluates to a number less than zero, the value is used as an offset in characters from the end of the value of <var>parameter</var>. If <var>length</var> evaluates to a number less than zero, it is interpreted as an offset in characters from the end of the value of <var>parameter</var> rather than a number of characters, and the expansion is the characters between <var>offset</var> and that result. Note that a negative offset must be separated from the colon by at least one space to avoid being confused with the ‘<samp>:-</samp>’ expansion. </p> <p>Here are some examples illustrating substring expansion on parameters and subscripted arrays: </p> <pre class="verbatim">$ string=01234567890abcdefgh +$ echo ${string:7} +7890abcdefgh +$ echo ${string:7:0} + +$ echo ${string:7:2} +78 +$ echo ${string:7:-2} +7890abcdef +$ echo ${string: -7} +bcdefgh +$ echo ${string: -7:0} + +$ echo ${string: -7:2} +bc +$ echo ${string: -7:-2} +bcdef +$ set -- 01234567890abcdefgh +$ echo ${1:7} +7890abcdefgh +$ echo ${1:7:0} + +$ echo ${1:7:2} +78 +$ echo ${1:7:-2} +7890abcdef +$ echo ${1: -7} +bcdefgh +$ echo ${1: -7:0} + +$ echo ${1: -7:2} +bc +$ echo ${1: -7:-2} +bcdef +$ array[0]=01234567890abcdefgh +$ echo ${array[0]:7} +7890abcdefgh +$ echo ${array[0]:7:0} + +$ echo ${array[0]:7:2} +78 +$ echo ${array[0]:7:-2} +7890abcdef +$ echo ${array[0]: -7} +bcdefgh +$ echo ${array[0]: -7:0} + +$ echo ${array[0]: -7:2} +bc +$ echo ${array[0]: -7:-2} +bcdef +</pre> <p>If <var>parameter</var> is ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the result is <var>length</var> positional parameters beginning at <var>offset</var>. A negative <var>offset</var> is taken relative to one greater than the greatest positional parameter, so an offset of -1 evaluates to the last positional parameter. It is an expansion error if <var>length</var> evaluates to a number less than zero. </p> <p>The following examples illustrate substring expansion using positional parameters: </p> <pre class="verbatim">$ set -- 1 2 3 4 5 6 7 8 9 0 a b c d e f g h +$ echo ${@:7} +7 8 9 0 a b c d e f g h +$ echo ${@:7:0} + +$ echo ${@:7:2} +7 8 +$ echo ${@:7:-2} +bash: -2: substring expression < 0 +$ echo ${@: -7:2} +b c +$ echo ${@:0} +./bash 1 2 3 4 5 6 7 8 9 0 a b c d e f g h +$ echo ${@:0:2} +./bash 1 +$ echo ${@: -7:0} + +</pre> <p>If <var>parameter</var> is an indexed array name subscripted by ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the result is the <var>length</var> members of the array beginning with <code>${<var>parameter</var>[<var>offset</var>]}</code>. A negative <var>offset</var> is taken relative to one greater than the maximum index of the specified array. It is an expansion error if <var>length</var> evaluates to a number less than zero. </p> <p>These examples show how you can use substring expansion with indexed arrays: </p> <pre class="verbatim">$ array=(0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h) +$ echo ${array[@]:7} +7 8 9 0 a b c d e f g h +$ echo ${array[@]:7:2} +7 8 +$ echo ${array[@]: -7:2} +b c +$ echo ${array[@]: -7:-2} +bash: -2: substring expression < 0 +$ echo ${array[@]:0} +0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h +$ echo ${array[@]:0:2} +0 1 +$ echo ${array[@]: -7:0} + +</pre> <p>Substring expansion applied to an associative array produces undefined results. </p> <p>Substring indexing is zero-based unless the positional parameters are used, in which case the indexing starts at 1 by default. If <var>offset</var> is 0, and the positional parameters are used, <code>$0</code> is prefixed to the list. </p> </dd> <dt><span><code>${!<var>prefix</var>*}</code></span></dt> <dt><span><code>${!<var>prefix</var>@}</code></span></dt> <dd> +<p>Expands to the names of variables whose names begin with <var>prefix</var>, separated by the first character of the <code>IFS</code> special variable. When ‘<samp>@</samp>’ is used and the expansion appears within double quotes, each variable name expands to a separate word. </p> </dd> <dt><span><code>${!<var>name</var>[@]}</code></span></dt> <dt><span><code>${!<var>name</var>[*]}</code></span></dt> <dd> +<p>If <var>name</var> is an array variable, expands to the list of array indices (keys) assigned in <var>name</var>. If <var>name</var> is not an array, expands to 0 if <var>name</var> is set and null otherwise. When ‘<samp>@</samp>’ is used and the expansion appears within double quotes, each key expands to a separate word. </p> </dd> <dt><span><code>${#<var>parameter</var>}</code></span></dt> <dd> +<p>The length in characters of the expanded value of <var>parameter</var> is substituted. If <var>parameter</var> is ‘<samp>*</samp>’ or ‘<samp>@</samp>’, the value substituted is the number of positional parameters. If <var>parameter</var> is an array name subscripted by ‘<samp>*</samp>’ or ‘<samp>@</samp>’, the value substituted is the number of elements in the array. If <var>parameter</var> is an indexed array name subscripted by a negative number, that number is interpreted as relative to one greater than the maximum index of <var>parameter</var>, so negative indices count back from the end of the array, and an index of -1 references the last element. </p> </dd> <dt><span><code>${<var>parameter</var>#<var>word</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>##<var>word</var>}</code></span></dt> <dd> +<p>The <var>word</var> is expanded to produce a pattern and matched according to the rules described below (see <a href="pattern-matching">Pattern Matching</a>). If the pattern matches the beginning of the expanded value of <var>parameter</var>, then the result of the expansion is the expanded value of <var>parameter</var> with the shortest matching pattern (the ‘<samp>#</samp>’ case) or the longest matching pattern (the ‘<samp>##</samp>’ case) deleted. If <var>parameter</var> is ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If <var>parameter</var> is an array variable subscripted with ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. </p> </dd> <dt><span><code>${<var>parameter</var>%<var>word</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>%%<var>word</var>}</code></span></dt> <dd> +<p>The <var>word</var> is expanded to produce a pattern and matched according to the rules described below (see <a href="pattern-matching">Pattern Matching</a>). If the pattern matches a trailing portion of the expanded value of <var>parameter</var>, then the result of the expansion is the value of <var>parameter</var> with the shortest matching pattern (the ‘<samp>%</samp>’ case) or the longest matching pattern (the ‘<samp>%%</samp>’ case) deleted. If <var>parameter</var> is ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If <var>parameter</var> is an array variable subscripted with ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list. </p> </dd> <dt><span><code>${<var>parameter</var>/<var>pattern</var>/<var>string</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>//<var>pattern</var>/<var>string</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>/#<var>pattern</var>/<var>string</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>/%<var>pattern</var>/<var>string</var>}</code></span></dt> <dd> +<p>The <var>pattern</var> is expanded to produce a pattern just as in filename expansion. <var>Parameter</var> is expanded and the longest match of <var>pattern</var> against its value is replaced with <var>string</var>. <var>string</var> undergoes tilde expansion, parameter and variable expansion, arithmetic expansion, command and process substitution, and quote removal. The match is performed according to the rules described below (see <a href="pattern-matching">Pattern Matching</a>). </p> <p>In the first form above, only the first match is replaced. If there are two slashes separating <var>parameter</var> and <var>pattern</var> (the second form above), all matches of <var>pattern</var> are replaced with <var>string</var>. If <var>pattern</var> is preceded by ‘<samp>#</samp>’ (the third form above), it must match at the beginning of the expanded value of <var>parameter</var>. If <var>pattern</var> is preceded by ‘<samp>%</samp>’ (the fourth form above), it must match at the end of the expanded value of <var>parameter</var>. If the expansion of <var>string</var> is null, matches of <var>pattern</var> are deleted. If <var>string</var> is null, matches of <var>pattern</var> are deleted and the ‘<samp>/</samp>’ following <var>pattern</var> may be omitted. </p> <p>If the <code>patsub_replacement</code> shell option is enabled using <code>shopt</code>, any unquoted instances of ‘<samp>&</samp>’ in <var>string</var> are replaced with the matching portion of <var>pattern</var>. This is intended to duplicate a common <code>sed</code> idiom. </p> <p>Quoting any part of <var>string</var> inhibits replacement in the expansion of the quoted portion, including replacement strings stored in shell variables. Backslash will escape ‘<samp>&</samp>’ in <var>string</var>; the backslash is removed in order to permit a literal ‘<samp>&</samp>’ in the replacement string. Users should take care if <var>string</var> is double-quoted to avoid unwanted interactions between the backslash and double-quoting, since backslash has special meaning within double quotes. Pattern substitution performs the check for unquoted ‘<samp>&</samp>’ after expanding <var>string</var>, so users should ensure to properly quote any occurrences of ‘<samp>&</samp>’ they want to be taken literally in the replacement and ensure any instances of ‘<samp>&</samp>’ they want to be replaced are unquoted. </p> <p>For instance, </p> <div class="example"> <pre class="example">var=abcdef +rep='& ' +echo ${var/abc/& } +echo "${var/abc/& }" +echo ${var/abc/$rep} +echo "${var/abc/$rep}" +</pre> +</div> <p>will display four lines of "abc def", while </p> <div class="example"> <pre class="example">var=abcdef +rep='& ' +echo ${var/abc/\& } +echo "${var/abc/\& }" +echo ${var/abc/"& "} +echo ${var/abc/"$rep"} +</pre> +</div> <p>will display four lines of "& def". Like the pattern removal operators, double quotes surrounding the replacement string quote the expanded characters, while double quotes enclosing the entire parameter substitution do not, since the expansion is performed in a context that doesn’t take any enclosing double quotes into account. </p> <p>Since backslash can escape ‘<samp>&</samp>’, it can also escape a backslash in the replacement string. This means that ‘<samp>\\</samp>’ will insert a literal backslash into the replacement, so these two <code>echo</code> commands </p> <div class="example"> <pre class="example">var=abcdef +rep='\\&xyz' +echo ${var/abc/\\&xyz} +echo ${var/abc/$rep} +</pre> +</div> <p>will both output ‘<samp>\abcxyzdef</samp>’. </p> <p>It should rarely be necessary to enclose only <var>string</var> in double quotes. </p> <p>If the <code>nocasematch</code> shell option (see the description of <code>shopt</code> in <a href="the-shopt-builtin">The Shopt Builtin</a>) is enabled, the match is performed without regard to the case of alphabetic characters. If <var>parameter</var> is ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the substitution operation is applied to each positional parameter in turn, and the expansion is the resultant list. If <var>parameter</var> is an array variable subscripted with ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the substitution operation is applied to each member of the array in turn, and the expansion is the resultant list. </p> </dd> <dt><span><code>${<var>parameter</var>^<var>pattern</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>^^<var>pattern</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>,<var>pattern</var>}</code></span></dt> <dt><span><code>${<var>parameter</var>,,<var>pattern</var>}</code></span></dt> <dd> +<p>This expansion modifies the case of alphabetic characters in <var>parameter</var>. The <var>pattern</var> is expanded to produce a pattern just as in filename expansion. Each character in the expanded value of <var>parameter</var> is tested against <var>pattern</var>, and, if it matches the pattern, its case is converted. The pattern should not attempt to match more than one character. </p> <p>The ‘<samp>^</samp>’ operator converts lowercase letters matching <var>pattern</var> to uppercase; the ‘<samp>,</samp>’ operator converts matching uppercase letters to lowercase. The ‘<samp>^^</samp>’ and ‘<samp>,,</samp>’ expansions convert each matched character in the expanded value; the ‘<samp>^</samp>’ and ‘<samp>,</samp>’ expansions match and convert only the first character in the expanded value. If <var>pattern</var> is omitted, it is treated like a ‘<samp>?</samp>’, which matches every character. </p> <p>If <var>parameter</var> is ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the case modification operation is applied to each positional parameter in turn, and the expansion is the resultant list. If <var>parameter</var> is an array variable subscripted with ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the case modification operation is applied to each member of the array in turn, and the expansion is the resultant list. </p> </dd> <dt><span><code>${<var>parameter</var>@<var>operator</var>}</code></span></dt> <dd> +<p>The expansion is either a transformation of the value of <var>parameter</var> or information about <var>parameter</var> itself, depending on the value of <var>operator</var>. Each <var>operator</var> is a single letter: </p> <dl compact> <dt><span><code>U</code></span></dt> <dd><p>The expansion is a string that is the value of <var>parameter</var> with lowercase alphabetic characters converted to uppercase. </p></dd> <dt><span><code>u</code></span></dt> <dd><p>The expansion is a string that is the value of <var>parameter</var> with the first character converted to uppercase, if it is alphabetic. </p></dd> <dt><span><code>L</code></span></dt> <dd><p>The expansion is a string that is the value of <var>parameter</var> with uppercase alphabetic characters converted to lowercase. </p></dd> <dt><span><code>Q</code></span></dt> <dd><p>The expansion is a string that is the value of <var>parameter</var> quoted in a format that can be reused as input. </p></dd> <dt><span><code>E</code></span></dt> <dd><p>The expansion is a string that is the value of <var>parameter</var> with backslash escape sequences expanded as with the <code>$'…'</code> quoting mechanism. </p></dd> <dt><span><code>P</code></span></dt> <dd><p>The expansion is a string that is the result of expanding the value of <var>parameter</var> as if it were a prompt string (see <a href="controlling-the-prompt">Controlling the Prompt</a>). </p></dd> <dt><span><code>A</code></span></dt> <dd><p>The expansion is a string in the form of an assignment statement or <code>declare</code> command that, if evaluated, will recreate <var>parameter</var> with its attributes and value. </p></dd> <dt><span><code>K</code></span></dt> <dd><p>Produces a possibly-quoted version of the value of <var>parameter</var>, except that it prints the values of indexed and associative arrays as a sequence of quoted key-value pairs (see <a href="arrays">Arrays</a>). </p></dd> <dt><span><code>a</code></span></dt> <dd><p>The expansion is a string consisting of flag values representing <var>parameter</var>’s attributes. </p></dd> <dt><span><code>k</code></span></dt> <dd><p>Like the ‘<samp>K</samp>’ transformation, but expands the keys and values of indexed and associative arrays to separate words after word splitting. </p></dd> </dl> <p>If <var>parameter</var> is ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the operation is applied to each positional parameter in turn, and the expansion is the resultant list. If <var>parameter</var> is an array variable subscripted with ‘<samp>@</samp>’ or ‘<samp>*</samp>’, the operation is applied to each member of the array in turn, and the expansion is the resultant list. </p> <p>The result of the expansion is subject to word splitting and filename expansion as described below. </p> +</dd> </dl><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.<br>Licensed under the GNU Free Documentation License.<br> + <a href="https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html" class="_attribution-link">https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html</a> + </p> +</div> |
