• bash八大扩展一网打尽


    最近在梳理bash知识的的过程中,有幸阅读了man bash文档,一时间犹如醍醐灌顶一般,很多当初不明白的地方都豁然开朗,现在就其中的一点做一分享,同时也为man bash做一下广告,当你面对bash问题孤立无援的时候,别忘了还有man bash的陪伴。
     
    Bash 支持的扩展种类有:brace expansiontilde expansionparameter and variable expansion,command substitutionarithmetic expansionword splitting, and pathname expansion(为了表述精确起见,这里就直接应用原文中的术语了)。还有一个叫:process substitution
     
    他们的优先级顺序为:brace expansion, tilde expansion, parameter, variable expansion, arithmetic expansion, command substitution , word splitting, pathname expansion

    brace expansion

    brace值得就是“{ }”。该扩展是用来生成字符串的,下面举两个例子:

    如果括号中间是“..”,则生成连续字符

    tilde expansion

    tilde值得就是“~”,我们都清楚~指的是HOME,这里还有另外两个,他们是“~+”和“~-”,分别代表PWD和OLDPWD,使用这两个可以刚方便我们的脚本编写,举个例子:

     

    Parameter expansion

    这个是bash中最重要、也是最常用的扩展,但整整了解他的人并不多,这里就来揭开它不为人知的另一面:
    它的标准形式为${parameter},简写为$parameter,使用${parameter}可以避免很多不必要的麻烦。

    • ${parameter : -word},如果parameter为空,或者根本没有定义parameter,则采用默认值,
    • ${parameter: =word},如果parameter为空,或者根本没有定义parameter,则赋予默认值

    上面两个的区别在于前者没有给parameter赋值,举个例子:

    • ${parameter :? word},如果parameter为空,或者根本没有定义parameter,则打印出错信息
    • ${parameter:+word},如果parameter取值不为空,则用word替换

    • ${parameter:offset}
    • ${parameter:offset:length}

    上面两个是用来截取指定长度字符串的,截取的下标offset从0开始计数,长度由length指定。如果没有指定length,则一直截取的末尾:

    • ${!prefix*}
    • ${!prefix@}

    这两个的意思相同,都是扩展成以prefix为开头的变量名称,同时会使用IFS的第一个变量把他们分隔开。例如:

    • ${!name[@]}
    • ${!name[*]}

    这两个是用来查询数组下标的。打印出来的是name数组有哪些下标。注意:这个和${name[@]},${name[*]}不同,这两个是打印的每个数组元素的内容,而我们这里在讲的这两个是打印的数组下标。例如:

    补充一点,如果你使用了associative array,他会自动取代下标为0的元素。例如:

    ${#parameter},打印parameter的长度,

    • ${parameter#word},使用pathname expansion把word作为一个pattern来扩展,从头开始扫描parameter,输出满足patter的最短匹配串。
    • ${parameter##word},使用pathname expansion把word作为一个pattern来扩展,从头开始扫描parameter,输出满足patter的最长匹配串。
    • ${parameter%word},使用pathname expansion把word作为一个pattern来扩展,从尾开始扫描parameter,输出满足patter的最短匹配串。
    • ${parameter%%word},使用pathname expansion把word作为一个pattern来扩展,从尾开始扫描parameter,输出满足patter的最长匹配串。
    • ${parameter/pattern/string},用string替换parameter中的pattern。从头扫描,pattern采用的是pathname expansion;替换第一个匹配
    • ${parameter//pattern/string},用string替换parameter中的pattern。从头扫描,pattern采用的是pathname expansion;替换所有匹配


    另外的,如果parameter是数组,那么数组的每个元素都采取相同的策略,如:

    command substitution

    很常用的功能,两种形式:$(command)和`command`,基本使用说,地球人都知道。但是如果要想嵌套怎么办呢?看了下面的例子你就明白了:

    对了,就是用反斜杠转移来实现嵌套。

    arithmetic expansion

    形式为:$((expression)),例如:

    Process Substitution

    这个扩展在开始没有提到。这个扩展使用了FIFO,所以,他只能在支持FIFO的系统中使用。他的形式为<(command list)或者>(command list)。用到这个扩展的时候,它会在/dev/fd中生成临时文件,用来接收command list的输出,然后,把里面的内容发送给当前的命令。这个命令在需要临时保存某几个命令的输出,并把输出用来后续处理的时候非常有用,可以避免生成过多临时文件。例如:

    从最后一条命令的输出可以看得出,这种替换是把中间的结果放到了两个临时文件中,它们是:/dev/fd/63和/dev/fd/62。命令完成后,这两个文件就会消失。

    Word splitting

    顾名思义,就是按照IFS分割输出,例如:

    pathname expansion

    就是我们常用的ls ? ls *。? * 的含义大家都清楚。但是这个扩展行为与set和shopt中个多个设置有关,现列举如下:

    • noglob -d 禁止用路径名扩展。即关闭通配符。(用set –o可以看到,后面的用shopt可以看到)
    • dotglob bash在文件名扩展的结果中包括以点(.)开头的文件名
    • extglob 打开扩展的模式匹配特征(正常的表达式元字符来自Korn shell的文件名扩展)
    • nocaseglob 如果设置,当执行文件名扩展时,bash在不区分大小写的方式下匹配文件名
    • nullglob 如果设置,bash允许没有匹配任何文件的文件名模式扩展成一个空串,而不是它们本身
    • failglob 如果pattern没有匹配到任意一个结果,则提示出错。

    含义说的很明白,这里不举例了

  • 相关阅读:
    [JSP] c:forEach 如何输出序号
    ckeditor_3.6.6.2+CKFinder2.0.2配置
    招聘面试技巧
    eclipse注释模板
    javadoc时候乱码-编码 GBK 的不可映射字符
    Java生成和操作Excel文件
    JOptionPane的使用
    2015内蒙古银行招聘网申注意事项
    Spring Security笔记:使用数据库进行用户认证(form login using database)
    中南大学oj:1336: Interesting Calculator(广搜经典题目)
  • 原文地址:https://www.cnblogs.com/welkinwalker/p/2910288.html
Copyright © 2020-2023  润新知