LinuxShellScriptingCookbook2
程序流程中常用的基本控制结构,包括顺序执行、比较和循环。本篇介绍Shell中的使用比较的方法。
比较与测试
主要使用if、ifelse和一些逻辑运算符进行比较,即:
if condition; |
条件一般是由一对[ ]
包裹或者一对[[ ]]
包裹的部分,if
和fi
组成一个完整的判断逻辑。
算数比较
注意: 在[和]与操作数之间有空格,缺少会报错。
if [ $VAR -eq 0 ]; |
-gt: 大于 ;-lt: 小于 ;-eq: 等于 ;-ge: 大于等于 ;-le: 小于等于
多个条件进行组合:
逻辑与: -a
,逻辑或:-o
,例如:
if [ $VAR -gt 1 -a $VAR -lt 4 ]; |
文件系统相关测试
[ -f $file_var ] # 给定变量包含正常文件路径或文件名,则返回真。 |
-x: 文件可执行; -d: 是目录;-e: 文件存在;-L: 是符号链接;-w: 文件可写;-r: 可读
字符串比较
字符串的比较,书中推荐使用双[]
,即:
[[ $str1 = $str2 ]] |
逻辑运算使用&&
和||
:
if [[ -n $str1 ]] && [[ -z $str2 ]] #str1非空而且str2是空的 |
test
test
等价于[]
,比如:
if test $var -eq 0; |
find命令
find可以遍历查找符合要求的文件。
根据文件名查找
find . -name "*.txt" # 查找当前目录下的txt文件 |
使用正则表达式匹配:
find . -regex ".*\(\.py\|\.sh\)$" #查找py和sh文件 |
使用否定参数和指定目录深度
find . ! -name "*.txt" -print # 匹配所有不以.txt结尾的文件名 |
按照文件类型查找
find . -type d -print # 目录 |
按照时间查找
find . -type f -atime -7 -print # 最近7天访问过的文件 |
按照文件大小
find . -type f -size +2M # 大于2M的文件 |
利用find执行命令或动作
主要使用-exec
:
find . -type f -mtime +10 -name "*.txt" -exec cp {} OLD \; |
%和#操作符
从”名称.扩展名”的格式中提取文名称或者扩展名,需要使用%
和#
:
非贪婪操作
${VAR%.*}
,即可得到从$VAR
中删除位于%
右侧匹配的字符而最终得到的字符串,从右往左匹配。例如:
file="hi.txt" |
输出为:
hi |
同理,使用{$VAR#*.}
,即可得到从$VAR
中删除位于#
右侧匹配的字符而最终得到的字符串,从左往右匹配。例如:
file="hi.txt" |
输出为:
txt |
仔细想想,这两个操作符一个是从右往左(%),一个是从左到右(#),都是删掉原始字符串中匹配到的部分得到想要的部分。
贪婪操作
上面的叫做非贪婪操作,原因是它们都只能按照顺序找到匹配通配符的最短结果进行删除。
比如对于hack.tar.gz
,使用%
和#
进行提取时,将会得到hack.tar
和tar.gz
。
而使用%%
和##
进行贪婪匹配,得到的结果就是hack
和gz
了。
合理对以上的几种操作符进行组合,可以完成很多有用的筛选:
比如对于tar.gz文件,用#
可以提取扩展名,用%%
可以提取文件名。