LinuxShellScriptingCookbook2

程序流程中常用的基本控制结构,包括顺序执行、比较和循环。本篇介绍Shell中的使用比较的方法。

比较与测试

主要使用if、ifelse和一些逻辑运算符进行比较,即:

if condition;
then
bye;
elif condition2;
then
bye2;
else
bye3;
fi

条件一般是由一对[ ]包裹或者一对[[ ]]包裹的部分,iffi组成一个完整的判断逻辑。

算数比较

注意: 在[和]与操作数之间有空格,缺少会报错。

if [ $VAR -eq 0 ];
then

-gt: 大于 ;-lt: 小于 ;-eq: 等于 ;-ge: 大于等于 ;-le: 小于等于

多个条件进行组合:

逻辑与: -a,逻辑或:-o,例如:

if [ $VAR -gt 1 -a $VAR -lt 4 ];
then
echo "$VAR > 1 and $VAR < 4";
fi

文件系统相关测试

[ -f $file_var ] # 给定变量包含正常文件路径或文件名,则返回真。

-x: 文件可执行; -d: 是目录;-e: 文件存在;-L: 是符号链接;-w: 文件可写;-r: 可读

字符串比较

字符串的比较,书中推荐使用双[],即:

[[ $str1 = $str2 ]]
[[ $str1 != $str2 ]]
[[ $str1 > $str2 ]] #字母序大
[[ $str1 < $str2 ]]
[[ -z $str1 ]] #如果包含空字符串,返回真
[[ -n $str1 ]] #如果包含非空字符串,返回真

逻辑运算使用&&||:

if [[ -n  $str1 ]] && [[ -z $str2 ]] #str1非空而且str2是空的

test

test等价于[],比如:

if test $var -eq 0;
then
echo "ture";
fi

find命令

find可以遍历查找符合要求的文件。

根据文件名查找

find . -name "*.txt" # 查找当前目录下的txt文件
find . -iname "*.txt" # 忽略大小写,查找TXT和txt文件
find . \( -name "*.txt" -o -name "*.pdf" \) -print # 查找txt和pdf文件

使用正则表达式匹配:

find . -regex ".*\(\.py\|\.sh\)$" #查找py和sh文件

使用否定参数和指定目录深度

find . ! -name "*.txt" -print # 匹配所有不以.txt结尾的文件名
find . -maxdepth 1 -name "f*" -print # 只匹配当前目录下以f开头的文件

按照文件类型查找

find . -type d -print # 目录
find . -type f -print # 普通文件
find . -type s -print # 套接字

按照时间查找

find . -type f -atime -7 -print # 最近7天访问过的文件
find . -type f -atime 7 -print # 恰好7天前访问过的文件
find . -type f -atime +7 -print # 7天以上时间之前访问过的文件
find . -type f -mtime -7 -print # 最近7天修改过的文件
find . -type f -ctime -7 -print # 最近7天文件元数据(权限或所有权)改动过的文件

按照文件大小

find . -type f -size +2M # 大于2M的文件

利用find执行命令或动作

主要使用-exec

find . -type f -mtime +10 -name "*.txt" -exec cp {} OLD \;
# 查找10天前的txt文件,并复制到OLD目录中。

%和#操作符

从”名称.扩展名”的格式中提取文名称或者扩展名,需要使用%#

非贪婪操作

${VAR%.*},即可得到从$VAR中删除位于%右侧匹配的字符而最终得到的字符串,从右往左匹配。例如:

file="hi.txt"
name=${file%.*}
echo $name

输出为:

hi

同理,使用{$VAR#*.},即可得到从$VAR中删除位于#右侧匹配的字符而最终得到的字符串,从左往右匹配。例如:

file="hi.txt"
name=${file#*.}
echo $name

输出为:

txt

仔细想想,这两个操作符一个是从右往左(%),一个是从左到右(#),都是删掉原始字符串中匹配到的部分得到想要的部分。

贪婪操作

上面的叫做非贪婪操作,原因是它们都只能按照顺序找到匹配通配符的最短结果进行删除。

比如对于hack.tar.gz,使用%#进行提取时,将会得到hack.tartar.gz

而使用%%##进行贪婪匹配,得到的结果就是hackgz了。

合理对以上的几种操作符进行组合,可以完成很多有用的筛选:

比如对于tar.gz文件,用#可以提取扩展名,用%%可以提取文件名。