shell编程
一、正则表达式
1.正则表达式分类
- 基本的正则表达式(Basic Regular Expression 又叫Basic RegEx 简称BREs)
- 扩展的正则表达式(Extended Regular Expression 又叫Extended RegEx 简称EREs)
- Perl的正则表达式(Perl Regular Expression 又叫Perl RegEx 简称PREs)
目前linux系统中有两套库可用于正则表达式编程,posix和pcre库,前者是linux自带的正则表达式库,后者是perl正则表达式库。从功能上来看,pcre更加强大,但是也更加难以掌握。以下对于正则表达式的描述均基于posix库。
2.正则表达式的使用
2.1使用实例
egrep "^a.*t$" /home/w/words.txt #查找words.txt中的以a开头t结尾的单词
2.2字符集和单词
- . : 用于匹配换行符之外的所有任意字符 .at可以匹配到 cat bat…
- [abc] : 用于匹配a b c但是不能匹配到ab ac bc abc这样的祝组合
- [a-z]/[a-zA-z]/[0-9]: 用于匹配到所有的小写字母或者是大小写字母,数字
- <[a-z]abc>:用于严格的匹配一个单词
shell对单词的定义:;两侧由非单词字符分割的字符串,非单词字符指的是字母、数字、下划线以外的任何字符
字符类
位置匹配"^ $"
“^ $”:分别位于表达式的行首和行尾,用于表示以某些字符开头和结尾的单词,两者不必同时存在。
字符转译""
shell中使用\标识字符的转译如 . 的真实含义在表达式中使用 .来表示
重复
egrep "^a.*t$" /home/w/words.txt #查找words.txt中的以a开头t结尾的单词
元字符 描述
子表达式"()"
子表达式也被称之为分组使用"()"来表示
实例
egrep "(or){2,}" /home/w/words.txt #查询words中or多次重复的单词
反义"^"
实例
[^y] :除了y以外的任何字母
注意:"^"在不同的位置由不同的含义,在表达式的开头,表示单词以某个字母开头,在表达式的其他位置表示反义
分支"|"
实例
“^a|b$”:以a开头或者是以b结尾的单词
逆向引用
“([ab][cd]).+( )\1" :\1表示重复第一个子表达式等同于"([ab][cd]).+( )([ab][cd])”
二、shell脚本编程
1.声明 #! /bin/bash
#! /bin/bash 告诉脚本应该使用那个shell程序
实例
#! /bin/bash
#输出一个hello world
echo "hello world!"
echo:控制台输出,输出末尾自动换行
2.变量
2.1变量声明
实例
your_name="ff"
变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
变量引用$
实例
#! /bin/bash
echo "${your_name}"
source:命令可以强行让一个shell脚本中的变量影响到其父环境
export:与source相反的命令,可以使父脚本中的变量被子脚本使用
实例
写一个配置JAVA环境变量的shell脚本
#!/bin/bash
export JAVA_HOME=/home/ff/java/jdk-1.8-8u20
export PATH=${JAVA_HOME}/bin:$PATH
source ./set_envirnoment #只在一次session中有效,从新开启窗口后环境变量脚本需要重新执行
3.位置变量 ${1},${2}…
shell中的位置变量和JAVA 、C等语言中的方法中的参数有些相似,
如mv命令 mv [source] [target]
位置变量就是用于接收这些参数的
- ${0}:脚本名称
- $1、${1}:接受第一个参数,{}中的数字表示接受的第几个参数,参数达到两位数后只能使用${},不能使用$
- $*:包含参数列表
- $@:同上
- $#:参数个数
4.引号规则
- 双引号:阻止shell对绝大多数的特殊字符进行解释(例如#),但是"$", “`”, " " "仍保留其特殊含义
- 单引号:阻止shell所有特殊字符进行解释
- 倒引号(esc下面的那个):当使用倒引号包含一段shell命令时,shell执行到该处时会执行包含的命令
5.运算符
-
原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
-
expr 1 + 2
-
$[ 1 + 2 ]
-
let $num = $num + 1
-
expr 是一款表达式计算工具,使用它能完成表达式的求值操作。 例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '):
#!/bin/bash val=`expr 2 + 2` echo "两数之和为 : $val"
两点注意:
-
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
-
完整的表达式要被倒引号包含,注意这个字符不是常用的单引号,在 Esc 键下边。
6.流程控制
-
shell中的test-command与JAVA中的不同,JAVA中的一般是command对应的是一个布尔值,而在shell中command对应的是一个命令,命令返回的结果为0时认为真,返回其他值的时候认为假
-
test数值测试命令
-
test字符串测试命令
-
test文件测试命令
-
-
if else-if else 语法格式:
if condition1 then command1 elif condition2 then command2 else commandN fi
#以下实例判断两个变量是否相等: a=10 b=20 if [ $a == $b ] #也可以使用test:test $a == $b then echo "a 等于 b" elif [ $a -gt $b ] then echo "a 大于 b" elif [ $a -lt $b ] then echo "a 小于 b" else echo "没有符合的条件" fi # 输出结果a 小于 b
-
for循环一般格式为:
for var in item1 item2 ... itemN # `seq 5` 生成一个1~5的列表 do command1 command2 ... commandN done
for loop in 1 2 3 4 5 do echo "The value is: $loop" done #输出结果 #The value is: 1 #The value is: 2 #The value is: 3 #The value is: 4 #The value is: 5
-
while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。其格式为:
while condition do command done
#!/bin/bash int=1 while $[ $int -le 5 ] do echo $int let "int++" done
-
until 语法格式:
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。until condition do command done
#!/bin/bash a=0 until [ ! $a -lt 10 ] do echo $a a=`expr $a + 1` done
-
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句格式如下:
case 值 in 模式1) command1 command2 ... commandN ;; 模式2) command1 command2 ... commandN ;; esac
case工作方式如上所示。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。如果无一匹配模式,使用星号 * 捕获该值,再执行后面的命令。
下面的脚本提示输入1到4,与每一种模式进行匹配:
echo '输入 1 到 4 之间的数字:' echo '你输入的数字为:' read aNum case $aNum in 1) echo '你选择了 1' ;; 2) echo '你选择了 2' ;; 3) echo '你选择了 3' ;; 4) echo '你选择了 4' ;; *) echo '你没有输入 1 到 4 之间的数字' ;; esac
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。#!/bin/bash while : do echo -n "输入 1 到 5 之间的数字:" read aNum case $aNum in 1|2|3|4|5) echo "你输入的数字为 $aNum!" ;; *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束" break ;; esac done
#!/bin/bash while : do echo -n "输入 1 到 5 之间的数字: " read aNum case $aNum in 1|2|3|4|5) echo "你输入的数字为 $aNum!" ;; *) echo "你输入的数字不是 1 到 5 之间的!" continue echo "游戏结束" ;; esac done
读取用户输入 read message
#! /bin/bash
read user
echo "欢迎您${user}!"
#输出结果欢迎您ff!
7.执行命令脚本
exit 0 退出并返回0
trap 捕获信号