条件判断是一个程序获得智能的基础,而Bourne Shell脚本则通过命令 [ 来模拟大多数编程语言中的条件表达式。

shell中支持的控制结构有:

(1) if then else fi

(2) for in do done

(3) while do done

这些关键字可以引导程序检查状态码 $?,从而实现控制。下面讲解这个命令如何模拟条件表达式。

文件/目录判断
[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。
[ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。
[ -d DIR ] 如果 FILE 存在且是一个目录则为真。
[ -e FILE ] 如果 FILE 存在则为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。
[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。
[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。
[ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。
[ -r FILE ] 如果 FILE 存在且是可读的则为真。
[ -s FILE ] 如果 FILE 存在且大小不为0则为真。
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。
[ -w FILE ] 如果 FILE存在且是可写的则为真。
[ -x FILE ] 如果 FILE 存在且是可执行的则为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。
[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。
[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。

字符串判断
[ -z STRING ] 如果STRING的长度为零则为真 ,即判断是否为空,空即是真;
[ -n STRING ] 如果STRING的长度非零则为真 ,即判断是否为非空,非空即是真;
[ STRING1 = STRING2 ] 如果两个字符串相同则为真 ;
[ STRING1 != STRING2 ] 如果字符串不相同则为真 ;
[ STRING1 ]  如果字符串不为空则为真,与-n类似

数值判断
INT1 -eq INT2 INT1和INT2两数相等为真 ,=
INT1 -ne INT2 INT1和INT2两数不等为真 ,<>
INT1 -gt INT2 INT1大于INT1为真 ,>
INT1 -ge INT2 INT1大于等于INT2为真,>=
INT1 -lt INT2 INT1小于INT2为真 ,<
INT1 -le INT2 INT1小于等于INT2为真,<=

总之,“=”用于比较字符串;“-eq”用于比较整型数

复杂逻辑判断
-a 与
-o 或
! 非

1、如果a>b且a<c
if (( a > b )) && (( a < c ))
if [[ $a > $b ]] && [[ $a < $c ]]
if [ $a -gt $b -a $a -lt $c ]

2、如果a>b或a<c
if (( a > b )) || (( a < c ))
if [[ $a > $b ]] || [[ $a < $c ]]
if [ $a -gt $b -o $a -lt $c ]

"||"和"&&"在SHELL里可以用,第一个可以写成if [ a>b && a ]

双括号和双中括号的含义见下文中对各种括号的解释。

Shell中的括号(), (()), [], [[]]

1、单小括号 ()
①命令组。括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用。括号中多个命令之间用分号隔开,最后一个命令可以没有分号,各命令和括号之间不必有空格。
②命令替换。等同于`cmd`,shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。注意花括号${}也可以被看做命令替换,但是两者有所区别,花括号内是定义好的变量,而不是shell命令。
③用于初始化数组。如:array=(a b c d)

2、双小括号 (( ))
①整数扩展。这种扩展计算是整数型的计算,不支持浮点型。((exp))结构扩展并计算一个算术表达式的值,如果表达式的结果为0,那么返回的退出状态码为1,或者 是"假",而一个非零值的表达式所返回的退出状态码将为0,或者是"真"。
②只要括号中的运算符、表达式符合C语言运算规则,都可用在$((exp))中。作不同进位(如二进制、八进制、十六进制)运算时,输出结果全都自动转化成了十进制。如:echo $((16#5f)) 结果为95 (16进位转十进制)。单纯用 (( )) 也可重定义变量值,比如 a=5; ((a++)) 可将 $a 重定义为6。双括号中的变量可以不使用$符号前缀。括号内支持多个表达式用逗号分开。
③甚至可以替代循环结构,只要括号中的表达式符合C语言运算规则。比如可以直接使用for((i=0;i<5;i++)), 如果不使用双括号, 则为for i in `seq 0 4`或者for i in {0..4}。再如可以直接使用if (($i<5)), 如果不使用双括号, 则为if [ $i -lt 5 ]。

3、单中括号 []
①标准命令 [ 和 test 是具有相同作用,区别在于 [ 命令的最后一个参数是 "]" 。
②在正则表达式中用于表示字符范围。作为test用途的中括号内不能使用正则。
④在一个array 结构的上下文中,中括号用来引用数组中每个元素的编号。

4、双中括号[[ ]]
①[[是 bash 程序语言的关键字,并不是一个命令。[[ ]] 结构比[ ]结构更加通用,不过注意[[ 依然要和中括号内的内容用空格隔开。
②支持字符串的模式匹配,使用=~操作符时支持正则表达式,使用==操作符时则支持通配符,字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。
③使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错,原因是 [ 命令不能解释&&的含义。比如可以直接使用if [[ $a != 1 && $a != 2 ]], 如果使用单括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]。
④bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。

语法提醒:shell有时靠命令来模拟运算。例如四则运算可以借助:let, expr 等命令完成。如对变量 x 加 1 可以写作:let "x = $x + 1" 或者 x=`expr $x + 1‘ 。如果参数有空格,一定要用引号括起来才不会出错。空格在shell中是有意义的。

PS:注意shell中,所有的输入都是字符串类型(当然任何语言都是如此,只是shell支持的类型解释和转换比较少),其中美元符$ 反引号` 反斜线\ 都被sh进程或者bash进程解释成字符串替换或命令替换,也就是用特定的输出字符串替换原命令,然后再继续执行新的命令。

调试:

查看shell脚本的执行过程
在执行的时候,通过下面的方式:
#sh -x test.sh

获取命令行参数:

注意 $ 是一个被解释成命令替换的符号,和反引号有类似之处。

$# 是传给脚本的单词个数
$0 是脚本本身的名字
$1 是传递给该shell脚本的第一个单词
$2 是传递给该shell脚本的第二个单词
$@ 是传给脚本的所有单词组成的列表数据结构
$* 将被替换成一个被包括在引号内的字符串,以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个
$$ 是脚本运行的当前进程ID号
$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

shell文本处理

重点掌握三个命令:find, grep, sed, awk,也就实现了对文本的增(插入)、删、改(替换)、查

1、find命令用于查找文件,如:

xin$ sudo find / -type f -size +1G

-name   filename             #查找名为filename的文件

用于查找磁盘上大于1G的文件。

2、grep命令用于查找文本,格式为:

grep <pattern> <filename>

3、sed命令用于编辑文本文件,最基本的命令当然是插入和删除,格式为:

sed [options] 'command' file(s) 注意用单引号而不是双引号,\ $ ` 等才不会被shell解释成字符串替换标志,而会直接把字面值转交给sed解释。

options:

-i :直接修改读取的文件内容,而不是将程序的结果输出到终端。

command:

格式 [n1,[n2]] function 其中 n1 和 n2 表示目标文本的首行行号和尾行行号

function:

a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)
c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行
d :删除,因为是删除啊,所以 d 后面通常不接任何字符串
i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行)
p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行
s :替换,可以直接进行取代的工作,通常这个 s 的动作可以搭配正规表示法,例如 1,20s/old/new/g

$:代表最后一行

示例:

替换:

Linux格式为:sed -i "s/192.168.0.2/192.168.0.3/g" *.rptdesign

Mac格式为:sed -i "" "s/192.168.0.2/192.168.0.3/g" *.rptdesign 相当于需要一个备份文件

删除:

sed -i "" '/^abc/d' ~/tmp/tmp.txt

插入:

sed -i "" '/192/a\
abc
' ~/tmp/tmp.txt

管道

示例: $ find .  | xargs svn add --force *.*

xargs命令会把从管道中获得的输入拆分,逐个作为下一个命令的输入。

Bourne Shell:控制语句、条件判断、文本处理、常用命令的更多相关文章

  1. 我们一起来学Shell - shell的条件判断

    文章目录 Shell 条件测试语法 符号说明 Shell 测试表达式 文件测试表达式 字符串测试表达式 整数操作符 逻辑操作符 测试表达式的区别总结 Shell 条件判断之if语句 单分支 IF 条件 ...

  2. shell中条件判断if中的-z到-d的意思

    shell中条件判断if中的-z到-d的意思 [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真. [ -c FILE ] 如果 ...

  3. Linux shell if条件判断2

    前面介绍linux shell的if判断的语法,现在再补充一点. Linux shell if条件判断1 分支判断结构     if , case   下面两个结构语法,已经在前面有过示例. 结构1: ...

  4. shell中条件判断if中的-z到-d

    shell中条件判断if中的-z到-d的意思 [ -a FILE ] 如果 FILE 存在则为真. [ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真.[ -c FILE ] 如果 ...

  5. shell test条件判断

    test 条件判断 # 符号 [ ] 等同  test命令 test -lt # 判断大小 echo $? # 查看上句test命令返回状态 # 结果0为真,1为假 test -n "hel ...

  6. linux文本处理常用命令

    linux文本处理常用命令   linux文本处理命令:grep.sed.printf.awk 1.grep grep的作用是按行查找字符,输出包含字符的行. #从文件查询 grep 'hello' ...

  7. Shell IF条件判断解析

    IF条件判断 1.基本语法: if [ command ]; then #符合该条件执行的语句 fi2.扩展语法: if [ command ];then #符合该条件执行的语句 elif [ com ...

  8. 第十三章、学习 Shell Scripts 条件判断式

    利用 if .... then 单层.简单条件判断式 if [ 条件判断式 ]; then 当条件判断式成立时,可以进行的命令工作内容: fi <==将 if 反过来写,就成为 fi !结束 i ...

  9. Linux之shell编程条件判断-if,while,for,case

    if 语法格式 if condition then statements [elif condition then statements] [else statements ] fi 示例 vi if ...

  10. shell中条件判断语法与判断条件小结

    1. IF条件判断语法: if Athen   dosthelif B   dosthelse   dosthfi 2. 判断条件:   2.1 字符串判断   str1 = str2 当两个串有相同 ...

随机推荐

  1. 2019年微信小程序1月TOP100榜单

  2. @InitBinder装配自定义编辑器

    @InitBinder装配自定义编辑器 第一步:BaseController.java,标注@InitBinder public class BaseController { @InitBinder ...

  3. 分水岭分割算法(watershed segmentation)的C++实现(法2)

    运行环境:ubuntu16.04+Qt+opencv2.4.13.3 watershed.cpp #include "opencv2/imgproc/imgproc.hpp" #i ...

  4. JS数组中级+高级技巧

    本文介绍JS数组一些比较进阶的方法: reverse:数组反转: join:(参数)以参数为连接符将数组拼接为字符串: 实例: var arr=[]; arr[3]="haha"; ...

  5. URL 生成带文字二维码

    <!DOCTYPE html> <html> <head> <title></title> <meta charset="u ...

  6. 【转】Python 中的 if __name__ == '__main__' 该如何理解

    转自:http://blog.konghy.cn/2017/04/24/python-entry-program/ 程序入口 对于很多编程语言来说,程序都必须要有一个入口,比如 C,C++,以及完全面 ...

  7. 【转】Ubuntu13.04配置:Vim+Syntastic+Vundle+YouCompleteMe

    原文网址:http://www.cnblogs.com/csuftzzk/p/3435710.html 序言 使用Ubuntu和vim已经有一段时间了,对于Vim下的插件应用,我总是抱着一股狂热的态度 ...

  8. .net 提取注释生成API文档 帮助文档

    提取注释生成API文档   一.前言 在多人协作的项目中,除了良好的代码规范外,完整的API文档也相当重要.通过文档我们快速了解系统各模块的实际接口,及其使用场景.使用示例,一定程度上降低沟通成本,和 ...

  9. Unable to locate \.nuget\NuGet.exe 问题解决办法之一

    问题出现的原因是项目下.nuget文件夹下NuGet.exe文件夹不存在导致的 解决办法: 1.右键编辑NuGet.targets文件 将下载NuGet.exe的配置节点DownloadNuGetEx ...

  10. TCP 3-Way Handshake (SYN,SYN-ACK,ACK)

    http://www.inetdaemon.com/tutorials/internet/tcp/3-way_handshake.shtml