bash 笔记 -- 10.2Parameter Substitution

440阅读 0评论2013-12-24 wuxiaobo_2009
分类:LINUX


点击(此处)折叠或打开

  1. 10.2 Parameter Substitution

  2. ${parameter}
  3.         与$parameter相同,就是parameter的值.当然 ${parameter} 更加严谨一点,如下:

  4. your_id=${USER}-on-${HOSTNAME} # $USER-on 明显就不对了,没有这个变量
  5. echo "$your_id"
  6. echo "Old \$PATH = $PATH"
  7. PATH=${PATH}:/opt/bin #Add /opt/bin to $PATH for duration of script.
  8. echo "New \$PATH = $PATH



  9.     
  10. ${parameter-default},${parameter:-default}

  11. 两个参数的作用: 如果变量没有设置,那么就用 default 来代替。

  12. eg.
  13.  #!/bin/bash
  14.  # param-sub.sh

  15.  # 一个变量是否被声明
  16.  #+ 将会影响默认选项的触发
  17.  #+ 甚至于这个变量被设为空.

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

  21.  echo

  22.  echo username1 has not been declared.
  23.  echo "username1 = ${username1-`whoami`}" # echo `who am i`的结果

  24.  username2=
  25.  echo "username2 has been declared, but is set to null."
  26.  echo "username2 = ${username2:-`whoami`}"
  27.  # ^
  28.  # 将会echo因为使用的是:-而不是 -.



  29.  # 再来一个:

  30.  variable=
  31.  # 变量已经被声明了,但是被设置为空.

  32.  echo "${variable-0}" # (no output)
  33.  echo "${variable:-1}" # 1
  34.  # ^

  35.  unset variable

  36.  echo "${variable-2}" # 2
  37.  echo "${variable:-3}" # 3

  38.  #再来
  39.  var1=''
  40.  echo "${var1-0}" # 空
  41.  echo "${var1:-0}" # 0
  42. # so,var1='' 等价于 var1= 但是不等价于 var1=NULL
  43.  exit
  44. ~

  45. 这个功能的作用: 设置默认值,如:有时候没有给出默认的文件名,用默认的来代替。
  46. DEFAULT_FILENAME=test.ora
  47. FILENAME=${1:-DEFAULT_FILENAME}

  48. # 上边的列子就是设置输出值,其中variable,$1,var1 等变量本身的值没有变


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


  50. ${username=`whoami`}
  51. # Variable "username" is now set to `whoami`.
  52. # 变量"username"被赋值为`whoami`

  53. 和上边的区别: var1=
  54.         echo ${var1:-'eee'}
  55.         echo $var1 #还是空
  56.         echo ${var1:='eee'}
  57.         echo $var1 #就是eee,变量本身变了


  58. 同时: = | := 这两个符号的区别同上边的一样,也是申明了但是空



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

  60. parameter 设置了,那么就显示 alt_value的值


  61. ################################Start Script#######################################
  62.  echo "###### \${parameter+alt_value} ########"
  63.  echo

  64.  a=${param1+xyz}
  65.  echo "a = $a" # a =

  66.  param2=
  67.  a=${param2+xyz}
  68.  echo "a = $a" # a = xyz

  69.  param3=123
  70.  a=${param3+xyz}
  71.  echo "a = $a" # a = xyz

  72.  echo
  73.  echo "###### \${parameter:+alt_value} ########"
  74.  echo

  75.  a=${param4:+xyz}
  76.  echo "a = $a" # a =

  77.  param5=
  78.  a=${param5:+xyz}
  79.  echo "a = $a" # a =
  80.  # 与a=${param5+xyz}有不同的结果. 注意观察: ${param5+alt_value}认为param5 设置了,而:+认为没有设置

  81.  param6=123
  82.  a=${param6+xyz}
  83.  echo "a = $a" # a = xyz

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

  85. # 如果parameter被set,那就是用set的值,否则print err_msg.

  86. eg.
  87. ${1?"Usage: $0 ARGUMENT"}


  88. 变量长度/子串删除:

  89. 字符串长度($var的字符数量).对于一个数组,${#array}是数组中第一个元素的长度.
  90. 一些例外:
  91.     ${#*}和${#@}将给出位置参数的个数.
  92.     对于数组来说${#array[*]}和${$#array[@]}将给出数组元素的个数.
  93. eg1.
  94. ###############################Start Script#######################################
  95.  1 #!/bin/bash
  96.  2 # patt-matching.sh
  97.  3
  98.  4 # 使用# ## % %%来进行参数替换操作的模式匹配.
  99.  5
  100.  6 var1=abcd12345abc6789
  101.  7 pattern1=a*c # * (通配符) 匹配a - c之间的任何字符.
  102.  8
  103.  9 echo
  104. 10 echo "var1 = $var1" # abcd12345abc6789
  105. 11 echo "var1 = ${var1}" # abcd12345abc6789
  106. 12 # (alternate form)
  107. 13 echo "Number of characters in ${var1} = ${#var1}"
  108. 14 echo
  109. 15
  110. 16 echo "pattern1 = $pattern1" # a*c (everything between 'a' and 'c')
  111. 17 echo "--------------"
  112. 18 echo '${var1#$pattern1} =' "${var1#$pattern1}" # d12345abc6789
  113. 19 # 最短的可能匹配, 去掉abcd12345abc6789的前3个字符
  114. 20 # |-| ^^^
  115. 21 echo '${var1##$pattern1} =' "${var1##$pattern1}" # 6789
  116. 22 # 最远的匹配,去掉abcd12345abc6789的前12个字符.
  117. 23 # |----------| ^^^^
  118. 24
  119. 25 echo; echo; echo
  120. 26
  121. 27 pattern2=b*9 # 'b' 到'9'之间的任何字符
  122. 28 echo "var1 = $var1" # 还是 abcd12345abc6789
  123. 29 echo
  124. 30 echo "pattern2 = $pattern2"
  125. 31 echo "--------------"
  126. 32 echo '${var1%pattern2} =' "${var1%$pattern2}" # abcd12345a
  127. 33 # 最近的匹配, 去掉abcd12345abc6789的最后6个字符
  128. 34 # |----| ^^^^
  129. 35 echo '${var1%%pattern2} =' "${var1%%$pattern2}" # a
  130. 36 # 最远匹配, 去掉abcd12345abc6789的最后12个字符
  131. 37 # |-------------| ^^^^^^
  132. 38
  133. 39 # 记住, # 和## 从字符串的左边开始,并且去掉左边的字符串,
  134. 40 # % 和 %% 从字符串的右边开始,并且去掉右边的子串.
  135. 41
  136. 42 echo
  137. 43
  138. 44 exit 0
  139. ################################End Script#########################################
  140. eg2.
  141. ################################Start Script#######################################
  142.  1 #!/bin/bash
  143.  2 # rfe.sh: 重命名文件扩展名.
  144.  3 #
  145.  4 # 用法: rfe old_extension new_extension
  146.  5 #
  147.  6 # 例子:
  148.  7 # 将指定目录的所有 *.gif 文件都重命名为 *.jpg,
  149.  8 # 用法: rfe gif jpg
  150.  9
  151. 10
  152. 11 E_BADARGS=65
  153. 12
  154. 13 case $# in
  155. 14 0|1) # "|" 在这里的意思是或操作.
  156. 15 echo "Usage: `basename $0` old_file_suffix new_file_suffix"
  157. 16 exit $E_BADARGS # 如果只有0个或1个参数,那么就退出.
  158. 17 ;;
  159. 18 esac
  160. 19
  161. 20
  162. 21 for filename in *.$1
  163. 22 # 以第一个参数为扩展名的全部文件的列表
  164. 23 do
  165. 24 mv $filename ${filename%$1}$2
  166. 25 # 从筛选出的文件中先去掉以第一参数结尾的扩展名部门,
  167. 26 #+ 然后作为扩展名把第2个参数添加上.
  168. 27 done
  169. 28
  170. 29 exit 0
  171. ################################End Script#########################################

  172. 变量扩展/子串替换
  173.     这些结构都是从ksh中吸收来的.

  174.     ${var:pos}
  175.         变量var从位置pos开始扩展.注意这里是从0 开始
  176.     var1=123456
  177.     echo ${var1:3:3} #4,5,6,不写lenth 默认就是到末尾
  178.     ${var:pos:len}
  179.         从位置pos开始,并扩展len长度个字符.见Example A-14(这个例子里有这种操作的一个
  180.         创造性用法)

  181.     ${var/Pattern/Replacement}
  182.         使用Replacement来替换var中的第一个Pattern的匹配.
  183.     ${var//Pattern/Replacement}
  184.         全局替换.在var中所有的匹配,都会用Replacement来替换.

  185.         向上边所说,如果Replacement被忽略的话,那么所有匹配到的Pattern都会被删除.



  186. eg1.
  187. ################################Start Script#######################################
  188.  1 #!/bin/bash
  189.  2
  190.  3 var1=abcd-1234-defg
  191.  4 echo "var1 = $var1"
  192.  5
  193.  6 t=${var1#*-*}
  194.  7 echo "var1 (with everything, up to and including first - stripped out) = $t"
  195.  8 # t=${var1#*-} 在这个例子中作用是一样的,
  196.  9 #+ 因为 # 匹配这个最近的字符串,
  197. 10 #+ 并且 * 匹配前边的任何字符串,包括一个空字符.
  198. 11 # (Thanks, Stephane Chazelas, for pointing this out.)
  199. 12
  200. 13 t=${var1##*-*}
  201. 14 echo "If var1 contains a \"-\", returns empty string... var1 = $t"
  202. 15
  203. 16
  204. 17 t=${var1%*-*}
  205. 18 echo "var1 (with everything from the last - on stripped out) = $t"
  206. 19
  207. 20 echo
  208. 21
  209. 22 # -------------------------------------------
  210. 23 path_name=/home/bozo/ideas/thoughts.for.today
  211. 24 # -------------------------------------------
  212. 25 echo "path_name = $path_name"
  213. 26 t=${path_name##/*/}
  214. 27 echo "path_name, stripped of prefixes = $t"
  215. 28 # 在这个特定的例子中,与 t=`basename $path_name` 的作用一致.
  216. 29 # t=${path_name%/}; t=${t##*/} 是一个更一般的解决办法,
  217. 30 #+ 但有时还是不行.
  218. 31 # 如果 $path_name 以一个新行结束, 那么`basename $path_name` 将不能工作,
  219. 32 #+ 但是上边这个表达式可以.
  220. 33 # (Thanks, S.C.)
  221. 34
  222. 35  t=${path_name%/*.*}
  223. 36 # 与 t=`dirname $path_name` 效果相同.
    37 echo "path_name, stripped of suffixes = $t"
    38 # 在某些情况下将失效,比如 "../", "/foo////", # "foo/", "/".
    39 #  删除后缀,尤其是在basename没有后缀的时候,
    40 #+ 但是dirname还是会使问题复杂化.
    41 # (Thanks, S.C.)
    42
    43 echo
    44
    45 t=${path_name:11}
    46 echo "$path_name, with first 11 chars stripped off = $t"
    47 t=${path_name:11:5}
    48 echo "$path_name, with first 11 chars stripped off, length 5 = $t"
    49
    50 echo
    51
    52 t=${path_name/bozo/clown}
    53 echo "$path_name with \"bozo\" replaced  by \"clown\" = $t"
    54 t=${path_name/today/}
    55 echo "$path_name with \"today\" deleted = $t"
    56 t=${path_name//o/O}
    57 echo "$path_name with all o's capitalized = $t"
    58 t=${path_name//o/}
    59 echo "$path_name with all o's deleted = $t"
    60
    61 exit 0
    ################################End Script#######################################



        ${var/#Pattern/Replacement}
            如果var的前缀匹配到了Pattern,那么就用Replacement来替换Pattern.

        ${var/%Pattern/Replacement}
            如果var的后缀匹配到了Pattern,那么就用Replacement来替换Pattern.

    Example 9-20 对字符串的前缀或后缀使用匹配模式
    ################################Start Script#######################################
     1 #!/bin/bash
     2 # var-match.sh:
     3 # 对字符串的前后缀使用匹配替换的一个样本
     4
     5 v0=abc1234zip1234abc    # 原始变量.
     6 echo "v0 = $v0"         # abc1234zip1234abc
     7 echo
     8
     9 # 匹配字符串的前缀
    10 v1=${v0/#abc/ABCDEF}    # abc1234zip1234abc
    11                         # |-|
    12 echo "v1 = $v1"         # ABCDEF1234zip1234abc
    13                         # |----|
    14
    15 # 匹配字符串的后缀
    16 v2=${v0/%abc/ABCDEF}    # abc1234zip123abc
    17                         #              |-|
    18 echo "v2 = $v2"         # abc1234zip1234ABCDEF
    19                         #               |----|
    20
    21 echo
    22
    23 #  ----------------------------------------------------
    24 #  必须在开头或结尾匹配,否则,
    25 #+ 将不会产生替换结果.
    26 #  ----------------------------------------------------
    27 v3=${v0/#123/000}       # 匹配上了,但不是在字符串的开头
    28 echo "v3 = $v3"         # abc1234zip1234abc
    29                         # 没替换.
    30 v4=${v0/%123/000}       # 匹配上了,但不是在字符串结尾.
    31 echo "v4 = $v4"         # abc1234zip1234abc
    32                         # 没替换.
    33
    34 exit 0    
    ################################End Script#########################################

    ${!varprefix*}, ${!varprefix@}
        使用变量的前缀来匹配前边所有声明过的变量.
        1 xyz23=whatever
        2 xyz24=
        3
        4 a=${!xyz*}      # 以"xyz"作为前缀,匹配所有前边声明过的变量.
        5 echo "a = $a"   # a = xyz23 xyz24
        6 a=${!xyz@}      # 同上.
        7 echo "a = $a"   # a = xyz23 xyz24
        8
        9 # Bash, version 2.04, 添加了这个特征.

    注意事项:
    [1]        如果在一个非交互脚本中,$parameter为空的话,那么这个脚本将以127返回.
            (127退出码对应的Bash错误码为"command not found").

上一篇:linux 的四种算数运算 不是浮点数
下一篇:Chapter 11. Loops and Branches --11.1 Loops