shell展开 | 青训营笔记

95 阅读1分钟
大括号展开(Brace Expansion) {...}

一般由三部分构成,前缀、一对大括号、后缀,大括号内可以是逗号分割的字符串序列,也可以是序列表达式{x..y[..incr]}

#字符串序列
a{b,c,d}e => abe ace ade
#表达式序列,(数字可以使用incr调整增量,字母不行)
{1...5} => 1 2 3 4 5
{1..5..2} => 1 3 5
{a..e} => a b c d e
波浪号展开(Tilde Expansion) ~
#当前用户主目录
~ => $HOME
~/foo => $HOME/foo
#指定用户的主目录
~fred/foo => 用户fred的$HOME/foo
#当前工作目录
~+/foo => $PWD/foo
#上一个工作目录
~-/foo => ${$OLDPWD-'~-'}/foo

$OLDPWD:保存跳转之前的路径

$PWD:保存当前的工作目录

参数展开(Shell Paramenter Expansion) ${}

1.间接参数扩展 ${!parameter},其中引用的参数并不是parameter而是parameter的实际的值

parameter="var"
var="hello"
echo ${!parameter}  // => ${var}
#输出hello

2.参数长度 ${#parameter}

par=cd
echo ${#par}
#输出2

3.空参数处理

${parameter:-word} #为空替换

${parameter:=word} #为空替换,并将值赋给$parameter变量

${parameter:?word} #为空报错

${parameter:+word} #不为空替换

a=1
echo ${a:-word} #1
echo ${b:-word} #word
echo ${par:=word} #word
echo ${par:-hello} #word
echo ${par:+foo} #foo

4.参数切片(类似于js数组的slice方法)

${parameter:offset}

${parameter:offset:length}

5.参数部分删除

${parameter%word} #最小限度从后面截取word

${parameter%%word} #最大限度从后面截取word

${parameter#word} #最小限度从前面截取word

${parameter##word} #最大限度从前面截取word

#!/bin/sh
str=abcdefg
sp1=${str##*d}
sp2=${str%%d*}
echo $sp1 #输出efg
echo $sp2 #输出abc
命令替换(Command Substitution)

在子进程中执行命令,并用得到的结果替换包裹的内容,形式上有两种:$(...)或...

#!/bin/bash
echo $(whoami)
foo(){
    echo "asdasd"
}
a=`foo`

echo $(whoami):输出当前登录的用户名

a=`foo`:调用函数 foo() 并将其输出结果赋值给变量 a,相当于执行了 a="asdasd"

数学计算(Arithmetic Expansion) $((..))

使用$(())包裹数学运算表达式,得到结果并替换

#!/bin/bash
echo $((1+2)) #3
文件名展开(Filename Expansion) * ?[..]外壳文件名模式匹配

当有单词没有被引号包裹,且其中出现了‘*’,‘?’,‘[’字符,则shell会去按照正则匹配的方式查找文件名进行替换,如果没找到则保持不变。

#!/bin/bash
$ echo D*
#输出当前目录下所有以D字母开头的目录、文件