前言
查资料时无意间看到这篇关于Shell中命令替换和参数扩展的博文,感觉写得十分通透给自己做一个参考。
什么是命令替换?
简单的来说就是在 SHELL 中嵌套多条命令,一次性执行得到结果。
一、一层SHELL嵌套
-
# echo `whoami`
-
# echo $(whoami)
-
# echo "hello,`whoami`"
-
# echo "hello,$(whoami)"
二、两层SHELL嵌套
# echo `cat ./gn2.txt` | sed -s "s;$; --list;"
使用 ``读取文件内容,再使用管道符二次处理后。执行!
注意:这里已经用了一层嵌套,以下多个小节会套用以实现两层嵌套。
a、使用“$()”进行两层嵌套
b、使用“|”进行命令导向
c、注意事项及一些解答
可能有读者已经注意到了,之前在简单 SHELL 一层嵌套中说了嵌套还有另一种。那为什么不使用 ` ` 进行嵌套。
- 根本的原因是:` ` 不支持命令嵌套执行!
强制执行。也只能认出第一组,其余按照空格作为间隔各个执行 或 按照管道符(含)直到末尾执行。
- 比较陈旧。容易与“单引号”混淆。
它是美式键盘左上角 ESC 下面的包含 ~ 的反引号键!
- 已有替代品。$(...) 格式受到POSIX标准支持,也利于嵌套。
$() 可以多层嵌套类似 $($($())) ,但如果内部有一个` ` 也是可以执行的哟(出于兼容考虑)!
三、进阶
1、(cmd)和{ var; }
关于 ( ) 与 { },和 命令替换 一样都是 shell 扩展 父类下的相关概念。
提示:{ } 头部大括号右侧必须有一个空格,尾部括号左侧必须有分号结尾。
-
# ( echo firest;echo second; )
-
# { echo third;echo fourth; }
注意: ( ) 只是对一串命令重新开一个 子 shell 进行执行, { } 对一串命令在 当前 shell 执行。
2、( )与{ }造成的影响
a.( ) 括号内的语句影响在括号内
-
# var=source
-
# ( echo $var;var=global;echo $var; )
-
# echo $var
b. { } 括号内的语句影响到全局。
-
# echo $var
-
# { echo $var;var=global;echo $var; }
-
# echo $var
注意:{ } 改变 var 的变量以后,外部也受到了影响。
什么是参数扩展?
参数扩展的基本格式是 ${ parameter },扩展的结果是 ${ parameter }被替换为相应的值。
1、实例一
-
echo $1 $11
-
echo $1 ${11}
首先解释下 ${1..9} 是什么意思。在我们写 Shell 时必不可免的需要传递参数以实现自定义变量。当超过阿拉伯数字 9 以后。就需要使用 ${ parameter } 明确告诉Shell 第 11 个参数是 ${11}。
提示:上图显示 101 就是因为 $11 不满足 [1-9]{1} 。系统将 11 拆分成 $1 和 1 ,所以运算后结果是 101
2、实例二
-
ban=ban
-
echo a $banana
-
echo a ${ban}ana
这个实例中,我想输出 banana 。已经定义了一个 ban 的变量为 ban ,只要加上 ana 就可以成为 “笨啦啦”。
但是很显然的不加 { } 是无法做到使变量 $ban 配合 ana 显示出 banana 的!
什么是变量扩展?
实例:
-
var='This is one test sentence.'
-
var1=parameter
-
var2=word
现在我们有了这样的一个句子,我希望做一些判断、摘取(或者说:切片)或修改。我该如何操作?
1、变量替换
a. ${parameter:-word}
-
# echo ${var1:-$var2}
-
parameter
-
# var1=
-
# echo ${var1:-$var2}
-
word
如果 var1 未设置或为空,则替换成 var2,但var1值不变。
b. ${parameter:=word}
同上,但是var1值同返回值。位置参数和特殊参数不能以这种方式分配。
c. ${parameter:?word}
-
# var1=
-
# echo ${var1:?var2}
-
bash: var1: var2
-
# echo $?
-
1
当变量 var1
未设置或为空,shell 也是可交互时,进行报错并且退出。如果 shell 不可交互,则发生变量替换。
c. ${parameter:+word}
-
# echo $var1
-
parameter
-
# echo $var2
-
word
-
# echo ${var1:+$var2}
-
word
-
# echo $var1
-
parameter
如果 var1
为空或未设置,那么就什么都不做。不然使用 var2
进行替换,var1值不变。
2、变量切片
a. 范围切片(同方向)
-
# echo ${var:8:17}
-
one test sentence
注意:俩个数字都是从头开始数的。
b. 范围切片(非同向)
-
# echo ${var:8:-1}
-
one test sentence
-
# echo ${var:8:(-1)}
-
one test sentence
注意:俩个数字都是从头开始数的。
c. 字符数量
-
# a='This is one'
-
# echo ${#a}
-
11
提示 :首先建立变量 a='This is one'
,然后使用 echo ${#a}
将字符数量读了出来。
3、变量修改
a.简单修改
-
# echo ${var}
-
This is one test sentence.
-
# echo ${var/one/a}
-
This is a test sentence.
提示:个人认为这种是最好的方式了,可以范围式修改(包含删除)。
b.简单删除
-
# echo ${var%sentence.}
-
This is one test
或
-
# echo ${var#This is}
-
one test sentence.
c.附表
变量设置方式 | 说明 |
---|---|
${变量#关键字} | 若变量内容从头开始的数据符合“关键字”,则将符合的最短数据删除 |
${变量##关键字} | 若变量内容从头开始的数据符合“关键字”,则将符合的最长数据删除 |
${变量%关键字} | 若变量内容从尾开始的数据符合“关键字”,则将符合的最短数据删除 |
${变量%%关键字} | 若变量内容从尾开始的数据符合“关键字”,则将符合的最长数据删除 |
${变量/旧字符串/新字符串} | 若变量内容符合“旧字符串”,则首个旧字符会被新字符替换。 |
${变量/旧字符串//新字符串} | 若变量内容符合“旧字符串”,则全部旧字符会被新字符替换。 |