1. 在 SHELL 中同时判断多个条件
在 SHELL if 语句中使用 "||" 和 "&&" 要用两个独立的 [ ]
if [ a -gt b ] && [ a -lt c ]
2. 判断字符串为空的方法
if [ "$str" = "" ]
if [ x"$str" = x ]
3. 截取字符串
${varible:start:len}
截取变量 varible 从位置 start 开始长度为 len 的子字符串。第一个字符的位置为0。
可以省略第三项,默认为一直到最右侧一个字符为止。如下示例 ${file:0:23}
中 start=0 表示从最左侧开始,len=23 表示截取长度为 23 个字符的子串,也即是到 index=22 的字符为止。
示例 ${file:23}
中 start=23 表示从 index=23 的字符开始,一直截取到最右一个字符结束。注意 index=23 和 len=23 的区别。
示例 ${file: -17}
中 start=-17 表示 index=-17 的字符开始,一直截取到最右一个字符结束。负号表示从右侧开始数起,最右一个字符为 -1,右侧倒数第二个为 -2,以此类推。注意冒号与负号之间有一个空格,一定不能省略,没有空格运行时会报错。
# hello_test.sh
abs_filepath="/home/phillee/test_tmp/hello_world_202104021730.mp4"
directory_path=${file:0:23}
base_filepath=${file:23}
postfix=${file: -17}
echo ${abs_filepath}
echo ${directory_path}
echo ${base_filepath}
echo ${postfix}
# console of the output
/home/phillee/test_tmp/hello_world_202104021730.mp4
/home/phillee/test_tmp/
hello_world_202104021730.mp4
_202104021730.mp4
4. 计算字符串长度
${#str}
5. 替换字符串
在 BashScript 中,pattern 是 glob 风格的
${var/pattern/substr} :首次。查找 var 所表示的字符串中,第一次被 pattern 所匹配到的字符串,以 substr 替换之。
${var//pattern/substr} :全部。查找 var 所表示的字符串中,所有能被 pattern 所匹配到的字符串,以 substr 替换之。
${var/#pattern/substr} :行首。查找 var 所表示的字符串中,行首被pattern所匹配到的字符串,以 substr 替换之。
${var/%pattern/substr} :行尾。查找 var 所表示的字符串中,行尾被pattern所匹配到的字符串,以 substr 替换之。
6. 格式化输出数字或字符串
比如我在 for 循环中处理完某些指令后,想要按照可以指示 for 循环的指数命名相应的文件,循环十次 0-9
,保存结果中后缀分别为 _00, _01, ..., _09
这种,当然可以简单粗暴使用 if 判断,但问题是有没有更简单的做法呢?
我觉得下面的这些处理方式相对而言更加普遍适用。
普通十进制数字直接使用 printf 重新赋值即可,%02d 表示格式化成 2 位有效数字,不足两位前面补零,d 表示处理整数。
a=$(printf "%02d" $a)
如果是浮点型数据,带小数点的小数这种,%2.1f 表示格式化为 2 位有效数字,小数点后保留一位,f 表示处理浮点型数据。
a=$(printf "%2.1f" $a)
字符串比较特殊一些,因为如果直接使用 printf 输出,%08s 表示格式化为 8 位长度的字符串,右对齐,不足八位的前面是空格,而不是数字 0,所以如果要以这种形式来处理的话,需要再加一步,将空格替换成0。s 表示按字符串处理。
a=$(printf "%08s" $a | tr " " "0")