最近在梳理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. 关于遍历javascript 中的json串浏览器输出的结果不统一的情况

    我们在做项目的时候经常会用到javascript的json. 首先说一下javascript的json串是什么,json串属于javascript的一个对象,有键和值对应的对象. 一般的格式是: a ...

  2. http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345bf0.html

    http://jingyan.baidu.com/article/f3ad7d0ffc061a09c3345bf0.html

  3. oracle 11g安装(转)

    原文地址:http://www.2cto.com/database/201208/150620.html 一.Oracle 下载 注意Oracle分成两个文件,下载完后,将两个文件解压到同一目录下即可 ...

  4. HDU1561 The more, The Better(树形DP)

    题目是有n个存有宝藏的城堡,攻克任何一个城堡都需要先攻克0个或其他1个城堡,问攻克m个城堡最多能得到多少宝藏. 题目给的城堡形成一个森林,添加一个超级根把森林连在一起就是树了,那么就考虑用树型DP: ...

  5. C#:代表(delegate)和事件(event)

    代表(delegate): 它是C#语言里面的函数指针,代表可以指向某一个函数,在运行的时候调用这个函数的实现.下面来看看它的实现步骤: 声明一个delegate对象. 实现和delegate具有相同 ...

  6. BZOJ3322 : [Scoi2013]摩托车交易

    求出最大生成树,则两点间的最大容量为树上两点间的边权的最小值. 设$lim[i]$表示第$i$个订单的城市允许携带的黄金上限,则 $lim[i]=\min(lim[i+1],a[i]和a[i+1]点间 ...

  7. storm源码之理解Storm中Worker、Executor、Task关系 + 并发度详解

    本文导读: 1 Worker.Executor.task详解 2 配置拓扑的并发度 3 拓扑示例 4 动态配置拓扑并发度 Worker.Executor.Task详解: Storm在集群上运行一个To ...

  8. TYVJ P1091 等差数列 Label:dp

    背景 广东汕头聿怀初中 Train#3 Problem 3 描述 等差数列的定义是一个数列S,它满足了(S[i]-S[i-1]) = d (i>1).显然的一个单独的数字或者两个数字也可以形成一 ...

  9. (转载)c# winform 用子窗体刷新父窗体,子窗体改变父窗体控件的值

    第一种方法: 用委托,Form2和Form3是同一组 Form2 C#代码 using System; using System.Collections.Generic; using System.C ...

  10. SQL Server 中 with tmp 临时表的用法

    SQL Server 中 with tmp 临时表的用法 ----------with临时表用法,有时候采用临时表比采用in的效率更高,避免了全表扫描. 实例中实现了查询普通题.大题.子题目的sql ...