1、常用的基本操作解析:
①${#string}
//返回$string的长度(字符串中的字符个数),${string} | wc -m也可以达到类似的效果
②${string:position}
//返回$string的position开始的字串(提取字串,不含pos)
③${string:position:length}
//返回$string的pos开始的长度为len的字串(不含pos),${string} | cut -c pos1-pos2y可以达到类似效果
④${string#substr}
//返回从变量$string开头开始不包含$substr的子串
⑤${string%substr}
//返回从变量$string结尾开始不包含最短匹配$substr的子串
⑥${string/substr/repalace}
//返回用replace替换substr之后的string(默认开头始)
⑦${string/#substr/replace}
//返回用replace替换substr之后的string(开头开始)
⑧${string/%substr/replace}
返回用replace替换substr之后的string(结尾开始)
注意:在以上操作过程中string是没有发生任何变化的
测试(可以看到program始终是没变的):
2、采用以上操作方式的应用案例:
(1)、用截断的操作方式批量修改文件名(删除一部分):
①先产生批量文件:
生成20个有着相似的文件名的文件以便于操作:
#!/bin/sh
#script-name:create.sh
for file in `seq -s " " 20`
do
touch "kangruojin_code_day${file}.c"
done
②批量修改文件名(删除一部分):
#!/bin/sh
#script-name:delpartname.sh
sh create.sh#先调用create.sh脚本产生操作的文件
for file in `ls *.c`
do
#通过mv命令将原来的文件名改为:通过${file#kangruojin_}删除kangruojin_前半部分的文件名。
/bin/mv $file ${file#kangruojin_}
done
(2)、用替换的操作方式批量修改后缀名:
#!/bin/sh
#change filename suffix from ".c" to ".cpp"
for file in `ls *.c`
do
#从尾部开始替换,用cpp替换c,然后修改名字
/bin/mv $file ${file/%c/cpp}
done
对于以上两种批量操作的测试如下:
脚本的强大之处立即显现了出来。
3、变量判断与替换的操作:
①${value:-world}
//如果变量名存在且非NULL,则返回变量的值,否则返回word字串。
②${value:=world}
//如果变量名存在且非NULL,则返回变量的值,否则设置这个变量的值为word并且返回word字符串。用途:保证变量存在且不为空。
③${value:? "not defined"}
//如果变量名存在且非NULL,则返回变量的值,否则返回"变量名:not defined" ,并退出当前命令/脚本。用于捕捉由于变量为定义而导致的错误,并且退出程序。
④${value:+world}
//如果变量名存在且非NULL,则返回word,否则返回NULL。
测试如下:
4、以上操作方式的应用案例:
由于上面的操作是判断变量存在与否、是否已经初始化。所以多用在安全操作的判断中。
如下案例:如果path路径不存在,为了防止不可预见的错误删除,虽然加了一层逻辑或的关系,但是我们将path不存在时的path初始化为“/tmp/”即会更加安全,并且不会删除不可预知的东西了:
5、效率问题:
最开始我们说,${#string}
与$string | wc -m
都可以测量长度,但是wc -m
(多一个字符是结束标志)。除了以上两种方式我们还可以用echo $(expr length "$string")
的方式测字符串长度:
但是哪一种方式效率高呢?我们用下面这个例子来测试:
/*循环测量10000次并用time测试程序执行时间*/
time for i in `seq 10000`;do cout=${#str};done
time for i in `seq 10000`;do cout=`echo {str} | wc -m`;done
time for i in `seq 10000`;do cout=$(expr length "$str");done
即如果如下:
可以发现${#string}
的效率最高,因为${#string}
是内置的,而wc命令是经过C语言写出的程序,经过一层包装所以效率最慢。而expr命令也是经过包装的,效率也差了十多倍(其差别在:wc与expr是浪费在了用户与内核的交互上,真正用来计算的时间差不了几倍),所以在脚本中能使用内置操作的尽量使用,而不要优先去使用现有的命令。