* | 匹配0或多个字符 | a*b a与b之前可以有任意长度的任意字符,也可以一个都没有 |
? | 匹配任意一个字符 | a?b a与b之间必须也只能有一个字符,可以是任意字符 |
[ ] | 匹配[ ] 中的任意单一字符 | a[xyz]b a与b之间必须也只能有一个字符 x,y,z a[!0-9]b a与b之间必须也只能有一个字符但不能是阿拉伯数字 |
{ } | 匹配{ } 中的字符串之一 | a{abc,xyz,123}b ab之间只能是此三个字符串之一 |
预定义变量
$$ 当前进程PID
$? 命令执行后的返回状态.0 为执行正确,非 0 为执行错误
$# 位置参数的数量
$* 所有位置参数的内容
$@ 所有的参数
$! 上一个后台进程的PID
自定义变量
定义:变量名称=值
变量名称:只能由字母,数字,下划线组成,不能以数字开头;
注意:应该让变量名称有意义;
= 赋值符号 前后不能有空格 ;
值: 所有的字符串和数字都可以;
引用变量: $变量名 或 ${变量名}。
环境变量
shell:在开始执行时已经定义好的
env :查看所有环境变量
set :查看所有变量
环境变量拥有可继承性:export之后就拥有继承性
export: 导出变量(作用范围)
算式运算符: +、-、*、/、()、%取余(取模)
(5+3)*2
运算方式:$(( )) $[ ] expr
echo $(($RANDOM%50+1)) 代表实现随机生成从1~50之间的数
bash本身不能做小数计算:需要bc命令转换
echo "2*4" | bc
#echo "2^4" | bc
#echo "scale=2;6/4" | bc
scale: 精度 bc -l -l数学库
转义: \ 当一个字符被引用时,其特殊含义被禁止 把有意义的变没意义,把没意义的变的有意义
完全引用:' ' //强引 硬引 部分引用: " " //弱引 软引
read:功能就是读取键盘输入的值,并赋给变量 (键盘输入)
read -p “后面内容为提示信息,需要打印出来” -s ‘后面的内容是加密信息,不要输出’ -t 超时时间
-eq
:等于-ne
:不等于-gt
:大于-ge
:大于等于-lt
:小于-le
:小于等于-z
:检查字符串是否为空-n
:检查字符串是否非空-e
:检查文件或目录是否存在-f
:检查文件是否存在,且是否为常规文件-d
:检查目录是否存在-r
:检查文件是否存在且可读-w
:检查文件是否存在且可写-x
:检查文件是否存在且可执行${parameter:-word} :若parameter为空或未设置,则word代替parameter进行替换,parameter值不变 (输入空变量时,word为默认选项,下次输入为空任为word)
${parameter:=word}:若parameter为空或未设置,则用word代替parameter进行替换,parameter值改变(输入空变量时,word为默认选项,当输入了名字时,下次空值,word变为上次输入)
${parameter:+word}:若parameter设置了,则用word代替parameter进行替换,parameter的值不变
${parameter:?message}:若parameter为空或未设置,message作为标志错误打印出来,可用来检查变量是否正确设置
echo ${a:5} //从第五位开始截取
echo ${a:3:4} //切除前三位,顺延留下四位
echo ${a:2:-1} //切除前两位和最后一位
file=/dir1/dir2/dir3/my.file.txt
${file#*/}: 拿掉第一条 / 及其左边的字符串:dir1/dir2/dir3/my.file.txt ${file##*/}: 拿掉最后一条 / 及其左边的字符串:my.file.txt
${file#*.}: 拿掉第一个 . 及其左边的字符串:file.txt
${file##*.}: 拿掉最后一个 . 及其左边的字符串:txt
${file%/*}: 拿掉最后条 / 及其右边的字符串:/dir1/dir2/dir3
${file%%/*}: 拿掉第一条 / 及其右边的字符串:(空值)
${file%.*}: 拿掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
${file%%.*}: 拿掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my
记忆的方法为:
# 是去掉左边(在键盘上 # 在 $ 之左边)
% 是去掉右边(在键盘上 % 在 $ 之右边)
basename 是去除目录后剩下的名字 ,不会检验文件系统,只是取路径的最后一段,将他截取
#temp=/home/temp/1.test
#base=`basename $temp`
#echo $base
结果为:1.test
dirname 是去除文件的目录名,不会检验文件系统,默认路径的最后一段为文件名,把他扇区
#temp=/home/temp/1.test
#dir=`dirname $temp`
#echo $dir
结果为:/home/temp
$( cd $( dirname $0 ) ; pwd ) #判断脚本的位置
test 能够理解3种类型的表达式
1.文件测试
2.字符串比较
3.数字比较
字符串
-n STRING
# -n 字符串长度不为零
-z STRING
# -z 字符串长度为0
STRING1 = STRING2
# = 判断两个字符串是否一样
STRING1 != STRING2
# != 判断两个字符串是否不一样
数字
eq 等于 ne 不等于 #
ge 大于等于 le 小于等于 #
gt 大于 lt 小于 #
文件
test
-f 存在且是普通文件 # 重要
-d 存在且是目录 #
-h 存在且是符号链接
-b 块设备
-c 字符设备
-e 文件存在 #
case $var in
模式1)
执行1
;;
模式2)
执行2
;;
模式3)
执行3
;;
*)
执行4
esac
for i in {取值范围} # for 关键字 i 变量名 in 关键字 取值范围格式 空格 制表符 换行
do # do 循环体的开始
循环体
done # done 循环体的结束
while 条件 # while 关键字 条件 [ $1 -lt 10 ] ,while循环,条件为真的情况下,会循环
do
循环体
done
until 条件 # 当后面的条件表达式,为假的时候进行循环,当他为真了就停止循环了。
do
循环体
done
break :结束并退出本次循环
continue : 在循环中不执行continue下面的代码,转而进入下一轮循环
exit :退出脚本,常带一整数给系统,如exit 0
在函数体内部,通过$n的形式来获取参数的值,例如,$1 表示第一个参数 $2 表示第二个参数
#!/bin/bash
fun() {
echo $[$1*$2*$3]
}
fun 1 2 3
例:
func(){
ping -W1 -c1 www.baidu.com &>/dev/null
if [ $? -eq 0 ];then
return 0
else
ping -W1 -c1 8.8.8.8 &>/dev/null
if [ $? -eq 0 ];then
return 10
else
ping -W1 -c1 192.168.100.2 &>/dev/null
if [ $? -eq 0 ];then
return 20
else
return 30
fi
fi
fi
}
func
result=$?
if [ $result -eq 0 ];then
echo "网络正常"
elif [ $result -eq 10 ];then
echo "DNS配置异常"
elif [ $result -eq 20 ];then
echo "当前网络环境异常"
else
echo "当前主机网络异常"
fi
当在脚本中定义数组时:例如 books=( linux shell awk sed )
此时他的数组的号可以定义为 books=( [0]=linux [1]=shell [2]=awk [3]=sed )
取出所有的元素
echo ${books[@]}
取出所有的索引
echo ${!books[@]}
取出索引的个数
echo ${#books[@]}
在数组中增加元素
books[4]="mysql"
修改数组中的某个值
books[0]="grep"
删除数组中的某个元素
unset books[0]
元字符 | 功能 | 示例 |
^ | 行首定位符 | ^love |
$ | 行尾定位符 | love$ |
. | 匹配单个字符 | l..e |
* | 匹配前导符0到多次,全部匹配grep “o*” /etc/passwd | ab*love |
.* | 匹配任意多个字符 | |
[ ] | 匹配方括号中任意一个字符 | [lL]ove |
[ - ] | 匹配指定范围内的一个字符 | [a-z0-9]ove |
[^] | 匹配不在指定组里的字符 | [^a-z0-9]ove |
\ | 用来转义元字符 | love\. |
\< | 词首定位符(由数字或字母组成) | \ |
\> | 词尾定位符 | love\> |
\(\) | 匹配后的标签(在vim中测试) | :%s@\(张三\) \(李四\) \(王五\)@ \3 \1 \2@g |
= 等于 != 不等于 =~ 匹配 运用正则判断需要 [ [ ] ]
+ | 匹配一个或多个前导字符 | [a-z]+ove |
? | 匹配零个或一个前导字符 | lo?ve |
"r.*t" | 贪婪匹配 -P "r.*?" 非贪婪匹配 | |
a|b | 匹配a或b | love|hate |
( ) | 组字符loveable|rs | love(able|rs) ov+ ov+(ov)+ |
(oo)+ | 两个oo出现一次或者多个 | |
(..)(..)\1\2 | 标签匹配字符 | (love)able\ler |
x{m} | 字符x重复m次 | o{5} |
o{,3} | 字符最多出现3次 | |
x{m,} | 字符x重复至少m次 | |
o{5,} | 字符最少出现5次 | |
x{m,n} | 字符x重复m到n次 | o{5,10} |
egrep支持正则表达式的拓展元字符 (或grep -E)
建议直接使用egrep
sed "参数" '模式'
参数: -f 指定一个规则文件,需求复杂的时候,需要匹配的内容多
-n 阻止输入行输出
-r 扩展正则,将匹配不到的现在可以匹配到了
sed 's/ma/ccccc/' file1.txt 用ccccc替换ma
sed -f 符合sed的文件 file1.txt 此处的符合sed的文件为此文件里所sed能执行的命令语句
sed -n 's/ma/ccccc/p' file1.txt 阻止输入行自动显示,取消默认输出
例子: sed '1d' passwd //删除文件的第1行
sed '1,2d' passwd //删除文件的第1到2行
sed -r 's#/etc/abc#/var/lib#' e.txt
sed '/root/d' passwd 匹配到root,删除此行
sed '/root/,2d' passwd 匹配到root行,到某一行
sed '1~2d' passwd 删除奇数行 从1开始删隔两行一删,包含第一行
sed '0~2d' passwd 删除偶数行
sed "s/\(.*\) = \(.*\)/\2 = \1/" /etc/my.cnf
1 2
此命令中\(.*\) = 表示等号两边的所有内容, \2 = \1 表示将1与2的位置对调
sed '/^#.*/d;/^$/d' /etc/ssh/sshd_config 删除sshd配置文件的注释和空行
awk 参数 'BEGIN{处理之前要做的} {处理内容} END{处理之后的内容}'
BEGIN{ } { } 行处理前,BEFGIN{ }在处理文本之前做的事情,只执行一次,{ }在处理文本时做的事情,有多少次执行多少次
END{ } 行处理 行处理后
awk工作原理
awk -F":" '{print $1,$3}' /etc/passwd
awk 'BEGIN{FS=":";OFS="---"}{print $1,$2,$3}' /etc/passwd
awk中的特殊变量:
常用:
- NR: 表示记录编号, 当awk将行为记录时, 该变量相当于当前行号
- NF: 表示字段数量, 当awk将行为记录时, 该变量相当于当前列号
难理解:
FS:(输入字段分隔符) # 以什么符号去分割
OFS:(输出字段分隔符) # 以什么分隔符显示
NR:(Number of record)行数
FNR:按不同的文件分开记录编号
RS :(输入记录分隔符) awk 'BEGIN{RS=" "}{print$0}' sararies.txt
ORS :(输出记录分隔符)
NF :字段个数
格式化打印:printf "%5s\t%5s\n" "hello" "world"
awk使用理解案例
1.打印文件第2列和第3列: awk '{ print $2, $3}' filename
2. 打印指定行指定列的某个字符 : awk -F":" 'NR==3{ print $7 }' /etc/passwd
3.统计一个文件的行数 : awk '{ print NR}' filename
4.在脚本中,传递变量到awk中: $ var=1000
$ echo | awk -v VARIABLE=$var '{ print VARIABLE }'
5.指定字段分隔符 -F或在BEGIN{ FS=":" } :awk -F: '{ print $2, $3 }' filename
$ awk 'BEGIN{ FS=":" }{ print $2, $3 }' filename