Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Advanced Bash Shell Scripting Gude.pdf
Скачиваний:
57
Добавлен:
17.08.2013
Размер:
4.82 Mб
Скачать

Parameter Substitution

 

Advanced Bash-Scripting Guide:

 

Prev

Chapter 9. Variables Revisited

Next

9.3. Parameter Substitution

Manipulating and/or expanding variables

${parameter}

Same as $parameter, i.e., value of the variable parameter. In certain contexts, only the less ambiguous ${parameter} form works.

May be used for concatenating variables with strings.

your_id=${USER}-on-${HOSTNAME} echo "$your_id"

#

echo "Old \$PATH = $PATH"

PATH=${PATH}:/opt/bin #Add /opt/bin to $PATH for duration of script. echo "New \$PATH = $PATH"

${parameter-default}

If parameter not set, use default.

echo ${username-`whoami`}

# Echoes the result of `whoami`, if variable $username is still unset.

This is almost equivalent to ${parameter:-default}. The extra : makes a difference only when parameter has been declared, but is null.

#!/bin/bash

username0=

#username0 has been declared, but is set to null. echo "username0 = ${username0-`whoami`}"

#Will not echo.

echo "username1 = ${username1-`whoami`}"

#username1 has not been declared.

#Will echo.

username2=

#username2 has been declared, but is set to null. echo "username2 = ${username2:-`whoami`}"

#Will echo because of :- rather than just - in condition test.

http://tldp.org/LDP/abs/html/parameter-substitution.html (1 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

exit 0

${parameter=default}, ${parameter:=default}

If parameter not set, set it to default.

Both forms nearly equivalent. The : makes a difference only when $parameter has been declared and is null, [1] as above.

echo ${username=`whoami`}

# Variable "username" is now set to `whoami`.

${parameter+alt_value}, ${parameter:+alt_value}

If parameter set, use alt_value, else use null string.

Both forms nearly equivalent. The : makes a difference only when parameter has been declared and is null, see below.

echo "###### \${parameter+alt_value} ########"

echo

a=${param1+xyz}

 

echo "a = $a"

# a =

param2=

 

a=${param2+xyz}

 

echo "a = $a"

# a = xyz

param3=123

 

a=${param3+xyz}

 

echo "a = $a"

# a = xyz

echo

echo "###### \${parameter:+alt_value} ########"

echo

a=${param4:+xyz}

 

 

echo "a = $a"

# a =

 

param5=

 

 

a=${param5:+xyz}

 

 

echo "a = $a"

# a =

 

# Different result from

a=${param5+xyz}

param6=123

 

 

a=${param6+xyz}

 

 

echo "a = $a"

# a = xyz

http://tldp.org/LDP/abs/html/parameter-substitution.html (2 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

${parameter?err_msg}, ${parameter:?err_msg}

If parameter set, use it, else print err_msg.

Both forms nearly equivalent. The : makes a difference only when parameter has been declared and is null, as above.

Example 9-12. Using param substitution and :

#!/bin/bash

#Check some of the system's environmental variables.

#If, for example, $USER, the name of the person at the console, is not set, #+ the machine will not recognize you.

:${HOSTNAME?} ${USER?} ${HOME?} ${MAIL?} echo

echo "Name of the machine is $HOSTNAME." echo "You are $USER."

echo "Your home directory is $HOME."

echo "Your mail INBOX is located in $MAIL." echo

echo "If you are reading this message,"

echo "critical environmental variables have been set." echo

echo

#------------------------------------------------------

#The ${variablename?} construction can also check

#+ for variables set within the script.

ThisVariable=Value-of-ThisVariable

# Note, by the way, that string variables may be set #+ to characters disallowed in their names.

: ${ThisVariable?}

echo "Value of ThisVariable is $ThisVariable". echo

echo

: ${ZZXy23AB?"ZZXy23AB has not been set."}

#If ZZXy23AB has not been set,

#+ then the script terminates with an error message.

#You can specify the error message.

#: ${ZZXy23AB?"ZZXy23AB has not been set."}

#Same result with: dummy_variable=${ZZXy23AB?}

#

dummy_variable=${ZZXy23AB?"ZXy23AB has not been set."}

#

 

#

echo ${ZZXy23AB?} >/dev/null

http://tldp.org/LDP/abs/html/parameter-substitution.html (3 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

echo "You will not see this message, because script terminated above."

HERE=0

exit $HERE # Will *not* exit here.

Parameter substitution and/or expansion. The following expressions are the complement to the match in expr string operations (see Example 12-6). These particular ones are used mostly in parsing file path names.

Variable length / Substring removal

${#var}

String length (number of characters in $var). For an array, ${#array} is the length of the first element in the array.

Exceptions:

${#*} and ${#@} give the number of positional parameters.

For an array, ${#array[*]} and ${#array[@]} give the number of elements in the array.

Example 9-13. Length of a variable

#!/bin/bash

# length.sh

E_NO_ARGS=65

if [ $# -eq 0 ] # Must have command-line args to demo script. then

echo "Invoke this script with one or more command-line arguments." exit $E_NO_ARGS

fi

var01=abcdEFGH28ij

echo "var01 = ${var01}"

echo "Length of var01 = ${#var01}"

echo "Number of command-line arguments passed to script = ${#@}" echo "Number of command-line arguments passed to script = ${#*}"

exit 0

${var#Pattern}, ${var##Pattern}

Remove from $var the shortest/longest part of $Pattern that matches the front end of $var.

A usage illustration from Example A-8:

http://tldp.org/LDP/abs/html/parameter-substitution.html (4 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

#Function from "days-between.sh" example.

#Strips leading zero(s) from argument passed.

strip_leading_zero () # Better to strip possible leading zero(s)

{

# from day and/or month

val=${1#0}

# since otherwise Bash will interpret them

return $val

# as octal values (POSIX.2, sect 2.9.2.1).

}

 

Another usage illustration:

 

 

 

echo `basename $PWD`

# Basename of current working directory.

echo "${PWD##*/}"

# Basename of current working directory.

echo

 

echo `basename $0`

# Name of script.

echo $0

# Name of script.

echo "${0##*/}"

# Name of script.

echo

 

filename=test.data

 

echo "${filename##*.}"

# data

 

# Extension of filename.

 

 

${var%Pattern}, ${var%%Pattern}

Remove from $var the shortest/longest part of $Pattern that matches the back end of $var.

Version 2 of Bash adds additional options.

Example 9-14. Pattern matching in parameter substitution

#!/bin/bash

# Pattern matching using the # ## % %% parameter substitution operators.

var1=abcd12345abc6789

pattern1=a*c # * (wild card) matches everything between a - c.

echo

 

 

 

echo "var1 = $var1"

# abcd12345abc6789

 

 

echo "var1 = ${var1}"

# abcd12345abc6789

(alternate form)

echo "Number of characters in ${var1} = ${#var1}"

 

 

echo "pattern1 = $pattern1" # a*c (everything between 'a' and 'c')

echo

 

 

 

echo '${var1#$pattern1}

=' "${var1#$pattern1}"

#

d12345abc6789

# Shortest possible match, strips out first 3 characters

abcd12345abc6789

#

^^^^^

 

|-|

echo '${var1##$pattern1} =' "${var1##$pattern1}"

#

6789

# Longest possible match, strips out first 12 characters

abcd12345abc6789

#

^^^^^

 

|----------|

http://tldp.org/LDP/abs/html/parameter-substitution.html (5 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

echo; echo

 

 

 

pattern2=b*9

# everything between 'b' and '9'

 

echo "var1 = $var1"

# Still abcd12345abc6789

 

 

echo "pattern2 = $pattern2"

 

 

echo

 

 

 

echo '${var1%pattern2}

=' "${var1%$pattern2}"

#

abcd12345a

# Shortest possible match, strips out last 6 characters

abcd12345abc6789

#

^^^^

 

|----|

echo '${var1%%pattern2} =' "${var1%%$pattern2}"

#

a

# Longest possible match, strips out last 12 characters

abcd12345abc6789

#

^^^^

 

|-------------|

#Remember, # and ## work from the left end of string,

#% and %% work from the right end.

echo

exit 0

Example 9-15. Renaming file extensions:

#!/bin/bash

 

#

rfe

#

---

#Renaming file extensions.

#rfe old_extension new_extension

#Example:

#To rename all *.gif files in working directory to *.jpg,

#rfe gif jpg

ARGS=2

E_BADARGS=65

if [ $# -ne "$ARGS" ] then

echo "Usage: `basename $0` old_file_suffix new_file_suffix" exit $E_BADARGS

fi

for filename in *.$1

# Traverse list of files ending with 1st argument. do

mv $filename ${filename%$1}$2

# Strip off part of filename matching 1st argument, #+ then append 2nd argument.

done

http://tldp.org/LDP/abs/html/parameter-substitution.html (6 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

exit 0

Variable expansion / Substring replacement

These constructs have been adopted from ksh. ${var:pos}

Variable var expanded, starting from offset pos. ${var:pos:len}

Expansion to a max of len characters of variable var, from offset pos. See Example A-14 for an example of the creative use of this operator.

${var/Pattern/Replacement}

First match of Pattern, within var replaced with Replacement.

If Replacement is omitted, then the first match of Pattern is replaced by nothing, that is, deleted. ${var//Pattern/Replacement}

Global replacement. All matches of Pattern, within var replaced with Replacement.

As above, if Replacement is omitted, then all occurrences of Pattern are replaced by nothing, that is, deleted.

Example 9-16. Using pattern matching to parse arbitrary strings

#!/bin/bash

var1=abcd-1234-defg echo "var1 = $var1"

t=${var1#*-*}

echo "var1 (with everything, up to and including first - stripped out) = $t"

#t=${var1#*-} works just the same, #+ since # matches the shortest string,

#+ and * matches everything preceding, including an empty string.

#(Thanks, S. C. for pointing this out.)

t=${var1##*-*}

echo "If var1 contains a \"-\", returns empty string... var1 = $t"

t=${var1%*-*}

echo "var1 (with everything from the last - on stripped out) = $t"

echo

#-------------------------------------------

path_name=/home/bozo/ideas/thoughts.for.today

#-------------------------------------------

echo "path_name = $path_name" t=${path_name##/*/}

echo "path_name, stripped of prefixes = $t"

http://tldp.org/LDP/abs/html/parameter-substitution.html (7 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

#

Same effect as

t=`basename $path_name` in this particular case.

#

t=${path_name%/}; t=${t##*/} is a more general solution,

#+ but still fails sometimes.

#If $path_name ends with a newline, then `basename $path_name` will not work, #+ but the above expression will.

#(Thanks, S.C.)

t=${path_name%/*.*}

# Same effect as t=`dirname $path_name` echo "path_name, stripped of suffixes = $t"

#These will fail in some cases, such as "../", "/foo////", # "foo/", "/".

#Removing suffixes, especially when the basename has no suffix,

#+ but the dirname does, also complicates matters.

# (Thanks, S.C.)

echo

t=${path_name:11}

echo "$path_name, with first 11 chars stripped off = $t" t=${path_name:11:5}

echo "$path_name, with first 11 chars stripped off, length 5 = $t"

echo

t=${path_name/bozo/clown}

echo "$path_name with \"bozo\" replaced by \"clown\" = $t" t=${path_name/today/}

echo "$path_name with \"today\" deleted = $t" t=${path_name//o/O}

echo "$path_name with all o's capitalized = $t" t=${path_name//o/}

echo "$path_name with all o's deleted = $t"

exit 0

${var/#Pattern/Replacement}

If prefix of var matches Pattern, then substitute Replacement for Pattern.

${var/%Pattern/Replacement}

If suffix of var matches Pattern, then substitute Replacement for Pattern.

Example 9-17. Matching patterns at prefix or suffix of string

http://tldp.org/LDP/abs/html/parameter-substitution.html (8 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

#!/bin/bash

# Pattern replacement at prefix / suffix of string.

v0=abc1234zip1234abc

# Original variable.

 

echo "v0 = $v0"

# abc1234zip1234abc

 

echo

 

 

 

# Match at prefix (beginning) of string.

 

v1=${v0/#abc/ABCDEF}

# abc1234zip1234abc

 

 

# |-|

 

 

echo "v1 = $v1"

# ABCDE1234zip1234abc

 

 

# |---

|

 

# Match at suffix (end) of string.

 

v2=${v0/%abc/ABCDEF}

# abc1234zip123abc

 

 

#

|-|

 

echo "v2 = $v2"

# abc1234zip1234ABCDEF

 

#

|----

|

echo

 

 

 

# ----------------------------------------------------

 

 

 

# Must match at beginning / end of string,

 

#+ otherwise no replacement results.

 

# ----------------------------------------------------

 

 

 

v3=${v0/#123/000}

# Matches, but not at beginning.

echo "v3 = $v3"

# abc1234zip1234abc

 

 

# NO REPLACEMENT.

 

v4=${v0/%123/000}

# Matches, but not at end.

echo "v4 = $v4"

# abc1234zip1234abc

 

 

# NO REPLACEMENT.

 

exit 0

${!varprefix*}, ${!varprefix@}

Matches all previously declared variables beginning with varprefix.

xyz23=whatever

xyz24=

a=${!xyz*}

# Expands to names of declared variables beginning with "xyz".

echo

"a = $a"

# a = xyz23 xyz24

a=${!xyz@}

# Same as above.

echo

"a = $a"

# a = xyz23 xyz24

# Bash, version

2.04, adds this feature.

Notes

[1]If $parameter is null in a non-interactive script, it will terminate with a 127 exit status (the Bash error code code for "command not found").

http://tldp.org/LDP/abs/html/parameter-substitution.html (9 of 10) [7/15/2002 6:35:10 PM]

Parameter Substitution

Prev

Home

Next

Manipulating Strings

Up

Typing variables: declare or typeset

http://tldp.org/LDP/abs/html/parameter-substitution.html (10 of 10) [7/15/2002 6:35:10 PM]