最近在梳理bash知识的的过程中,有幸阅读了man bash文档,一时间犹如醍醐灌顶一般,很多当初不明白的地方都豁然开朗,现在就其中的一点做一分享,同时也为man bash做一下广告,当你面对bash问题孤立无援的时候,别忘了还有man bash的陪伴。

Bash 支持的扩展种类有:brace expansion, tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, word 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没有匹配到任意一个结果,则提示出错。

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

SHELL 八大扩展的更多相关文章

  1. shell变量扩展技巧

    SHELL中有一些变量扩展的技巧,做下归纳总结 1.取字符串slice规则一:${变量名:位置起点}含义:由指定的位置起点开始,截取子字符串到字符串结束例如: var="/etc/passw ...

  2. Linux Shell参数扩展(Parameter Expansion)

    Shell Command Language在线文档: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html ...

  3. shell参数扩展

    http://zuyunfei.com/2016/03/23/Shell-Truncate-File-Extension/

  4. SHELL脚本扩展

    使用SED命令 sed称为流编辑器,命令格式如下: sed option script file -e script #指定多个命令 -f script_file #指定命令文件 -n #不需要为每个 ...

  5. [翻译].NET Shell Extensions - Shell Context Menus---.net 外壳扩展-右键菜单

    我自己的前言说明: 本文原作者为    Dave Kerr,原文链接为.NET Shell Extensions - Shell Context Menus:,我是在为了完成最新需求的时候查询资料的时 ...

  6. 【ASP.NET MVC系列】浅谈ASP.NET MVC八大类扩展(上篇)

    lASP.NET MVC系列文章 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google Chrome浏览器(操 ...

  7. 如何使用 GNOME Shell 扩展

    如何使用 GNOME Shell 扩展 作者: Abhishek Prakash 译者: LCTT MjSeven | 2018-03-15 10:53   评论: 1 简介:这是一份详细指南,我将会 ...

  8. shell之条件表达式

    conditional expressions are used by the [[ compound command and the test and [ builtin commands. ari ...

  9. 【转】Linux 技巧: Bash 参数和参数扩展

    重点看下清单7 现在,很多 Linux® 和 UNIX® 系统上都有 bash shell,它是 Linux 上常见的默认 shell.通过本文,您将了解到如何在 bash 脚本中处理参数和选项,以及 ...

随机推荐

  1. Linphone iOS客户端编译时打开G729支持

    Assuming you were able to compile the SDK and the linphone XCode project, here is what you need to d ...

  2. JavaScript中两个感叹号(!!)的作用是什么?

    !!一般用来将后面的表达式强制转换为布尔类型的数据(boolean),也就是只能是true或者false. 看这么个例子: var a: var b=!!a; a默认是undefined.!a是tru ...

  3. HDU3037 Saving Beans(Lucas定理+乘法逆元)

    题目大概问小于等于m个的物品放到n个地方有几种方法. 即解这个n元一次方程的非负整数解的个数$x_1+x_2+x_3+\dots+x_n=y$,其中0<=y<=m. 这个方程的非负整数解个 ...

  4. 分类 kNN

    #coding=utf-8 from numpy import * import operator from os import listdir import matplotlib import ma ...

  5. BZOJ4295 : [PA2015]Hazard

    第i轮,a[i%n]+=b[i%m]. 枚举i,计算它变为0的次数,假设为t,那么有t=i+kn. 对于所有的i和k,(i+kn)%m形成了若干个总长度为m的环. 对于每个a[i],先在环中求出一轮最 ...

  6. access-Control-Allow-Origin跨域请求安全隐患

    最新的W3C标准里是这么实现HTTP跨域请求的,Cross-Origin Resource Sharing,就是跨域的目标服务器要返回一系列的Headers,通过这些Headers来控制是否同意跨域. ...

  7. 初始Python类

    一.定义类.子类.类的实例化.子类的实例化.继承.实例属性和实例方法 示例: class Fruit(): ''' 定义一个水果类,包含水果的一些属性和一些方法. ''' def __init__(s ...

  8. Odoo ir value 分析

    源代码位置:openerp/addons/base/ir/ir_values.py _columns = { 'name': fields.char('Name', required=True), ' ...

  9. cmd下常用的一些命令

    1.calc计算器 2.Mspaint画图 3.Netstat -anb查看端口 输入netstat -anb时可能会遇到下面问题 只要到搜索框输入cmd,然后到其快捷方式上右击以管理员身份运行即可 ...

  10. Export-XLSX PowerShell generate real Excel XLSX files without Excel and COM

    http://gallery.technet.microsoft.com/scriptcenter/Export-XLSX-PowerShell-f2f0c035