一、1、基础正则表达式: * 前一个字符匹配0次或任意多次 . 匹配除了换行符外任意一个字符 ^ 匹配行首,例:^Hello,匹配以Hello开头的行 $ 匹配行尾,例:Hello$匹配以Hello结尾的行 [] 中括号中指定的一个字符,例:[0-9]、[a-z] [^] 匹配中括号字符以外的任意一个字符,例:[^0-9]、[^a-z] \ 转义符,取消特殊符号的含义 \{n\} 表示其前面的字符恰好出现n次,例:[0-9]\{4\}、手机号[1][3-8][0-9]\{9\} \{n,\} 表示其前面的字符出现不小于n次,例:[0-9]\{2,\}表示2位以上的数字 \{n,m\} 表示其前面的字符至少出现n次,最多出现m次,例:[a-z]\{6,8\}表示6到8位小写字母 2、扩展正则表达式:#grep–E 或 egrep + 前一个字符匹配1次或任意多次 ? 前一个字符出现0次或1次,例:colou?r匹配colour和color | 匹配两个或多个分支选择,例:was|his,匹配包含was的行,也包含his的行 () 匹配其整体为一个字符,即模式单元,可理解为由多个单个字符组成的大字符,例:(dog)会出现dog,dogdog,dogdogdog等;hello(world|earth),匹配hello worlda或hello earth 注:grep、awk、sed等命令支持正则表达式;ls、find、cp支持shell通配符 3、#grep “a*” t.txt (匹配任何内容 #grep“aa*” t.txt (匹配至少包含一个a的行 #grep“aaa*” t.txt (匹配至少包含二个a 的行 #grep“s..d” t.txt (匹配s和d之间一定有2个字符的单词 #grep“s.*d” t.txt (匹配s和d之间有任意个字符 #grep“^M” t.txt (匹配以M开头的行 #grep“N$” t.txt (匹配以N结尾的行 #grep“^$” t.txt (匹配空白行 #grep“^….$” t.txt (匹配四个字符的行 #grep“[0-9]” t.txt (匹配含数字的行 #grep“^[a-z]” t.txt (字母开头的行 #grep“[^A-Z]” t.txt (非大写字母的行 #grep“\.$” t.txt (以点结尾的行 #grep“a\{3\}” t.txt (三个连续a的行 #grep“[0-9]\{3,\} t.txt (至少三个数字开头的行 #grep“[su]a\{3,\}[iI] t.txt (s或u和i或I之间至少有三个连续的a #grep“sa\{1,3\}i” t.txt (s和i之间最少有1个a最多有3个a 二、字符截取和替换命令 1、#cut 选项 文件名 -f列号 fields提取第几列 -d“分隔符” delimiter指定分隔符 -c字符范围 通过字符范围进行字段提取,行首为0;“n-”表示从第n个字符到行尾;“n-m”表示从第n个字符到第m个字符;“-m”表示从第1个字符到第m个字符 例:#cut –f 2s.txt #cut–f 2,3 s.txt #cut–c 8- s.txt #cut–d “:” –f 1,3 s.txt 2、awk编程 >#printf ’输出类型输出格式’ 输出内容 输出类型: %ns 输出字符串,n指代输出几个字符 %ni 输出整数,n指代输出几个数字 %m.nf 输出浮点数,m代表总数位,n是小数位。例:%8.2f表示6位整数,2位小数 例:#printf ‘%s’$(cat s.txt) #printf‘%s\t%s\t%s\t%s\t \n’ $(cat s.txt) #printf‘%i\t%s\t%i\t%8.2f \n’ $(cat s.txt) | grep –v Name 动作:格式化输出,流程控制语句 注:在awk编程中因命令语句长,输入格式时需注意: 》多个条件{动作}可用空格分割也可用回车分割; 》在一个动作中,如果需要执行多个命令,要用分号分割或用回车分割; 》变量的赋值与调用都不用加$符号; 》条件判断两个值是否相同使用==,不要和变量赋值混淆。 例:#awk ‘{printf$2 “\t” $6 “\t” “\n” }’ s.txt (printf输出时在输出格式的最后要加“\n”,而print则不用。 #df–h | awk ‘{print $2 “\t” $6}’ s.txt #cats.txt | grep –v Name | awk ‘$6 >= 87 {print $2}’ (加入条件后,只有条件成立动作才执行 #awk‘BEGIN {print “this is a transcript”} {print $2 “\t” $6}’ s.txt (awk只要检测不到完整的‘’就不会执行,所以不用加换行符;BEGIN在读取数据前仅执行一次 #awk‘END {print “The end!”} {print $2 “\t” $3}’ s.txt #awk‘$2 ~ /sb/ {print $6}’ s.txt (第二个字段包含有sb则打印第六字段 #awk‘/sd/ {print}’ s.txt (打印sd的成绩 #df–h | awk ‘/sda[0-9]/ {print $1 “\t” $5}’ #cat/etc/passwd | grep “/bin/bash” | awk ‘BEGIN{FS=”:”} {print $1 “\t” $3}’ #cat/etc/passwd | grep “/bin/bash” | awk ‘BEGIN{FS=”:”} {print $1 “\t” $3 “\t 行号:”\ >NR “\t 字段数: “ NF}’ (NR总数据的第几行,NF总字段数 注:awk是列提取命令,但也要按行来读入,执行过程: 》如有BEGIN,则先执行BEGIN定义的动作; 》读入第一行,第一行的数据依次赋予$0,$1,$2等变量,$0代表此行的整体数据,$1代表第一个字段,$2代表第二个字段; 》依据条件判断动作是否执行,符合执行,否则读入下一行数据,若没条件,则每行都执行动作 》读入下一行数据,重复以下步骤。 #awk‘NR==2 {php1=$3} NR==3{php2=$3} NR==4{PHP=$3;total=php1+php2+php3;print”total php is ” total}’ s.txt
#awk‘NR>=2 {test=$4} test>90{print $2 “is a good man!”}’ s.txt
function函数名 (参数列表){ 函数体 } #awk ‘functiontest(a,b) {print a “\t” b} {test($2,$6)}’ s.txt
#vipass.awk BEGIN‘{FS=”:”} {print$1 “\t” $3} #awk–f pass.awk /etc/passwd
3、sed(streameditor,对文本文件和标准输入进行编辑,键盘输入、文件重定向、字符串、变量、来自管道的文本 #sed选项 ‘动作’文件名 -n 有此项,输出时只会显示sed处理的行 -e 对输入数据应用多条sed命令编辑 -f脚本文件 与#awk –f类似 -r 支持正则表达式 -I 直接修改源文件中数据,而不是由屏幕输出 动作: a\ append追加,在当前行后添加一行或多行,每行末尾用\代表数据未完,最后一行不用 c\ 行替换,用c后面的字符串替换原数据行,多行时用\代表数据未完,最后一行除外 i\ insert在当前行前插入一行或多行,多行时每行末尾用\代表数据未完,最后一行除外 d 删除指定的行 p 打印输出指定的行 s 字符替换,格式:行范围s/旧字串/新字串/g 行数据操作:例子: #sed–n ‘2p’ s.txt #sed‘2,4d’ s.txt #sed‘2a hello’ s.txt #sed‘2i hello \ >world’s.txt (行末用\代表数据未完,在第二行前插入两行数据 #sed–n ‘2i’ hello \ >world’s.txt (仅显示处理的行 #cats.txt |sed ‘2c No such person’ (将第二行替换 #sed–i ‘2c No such a person’ s.txt(直接处理文件数据,-i谨慎使用 字串替换:例子: #sed‘s/旧/新/g’ s.txt #sed‘3s/74/99/g’ s.txt #sed‘4s/^/#/g’ s.txt #sed–e ‘s/sb//g ; s/sd//g’ s.txt 三、字符处理命令 》#sort 选项 文件名 -f 忽略大小写ignore-case(foldlower case to upper case characters) -b 忽略每行前面的空白部分ignoreleading blanks -n 以数值排序numeric-sort -r 反射排序reverse -u 排除重复行,同uniqu命令 -t 指定分隔符,默认是制表符 -kn[,m] 按指定的字串范围,从n字段开始,m字段结束(默认到行尾) 例:#sort/etc/passwd #sort–r /etc/passwd #sort–t “:” –k 3,3 /etc/passwd (只用第3字段排序 #sort–n –t “:” –k 3,3 /etc/passwd 》#uniq 选项 文件名 (-i 忽略大小写 》#wc 选项 文件名 (-l,line;-w,word;-m字符数 四、条件判断 1、文件类型判断: 例:#[ -e /root/sh/ ] #echo$? #[ -d /root/sh ] && echo “yes”|| echo “no” 2、文件权限判断: #[ -w s.txt ]&& echo “yes” ||echo “no” 3、两个文件之间进行比较: #[ /root/s.txt -ef /tmp/sut.txt ] && echo “yes”|| echo "no” (判断是否硬链接 4、两个整数之间比较: #[ 23 -ge 22 ]&& echo “yes” || echo “no” 5、字符串的判断: #[ -z “$name” ] && echo “yes” || echo “no” 6、多重条件判断: #[ -n “$aa” -a -n “$aa” -gt 23] && echo “yes” || echo “no” 五、流程控制: 1、if条件判断: 》单分支: if[ 条件判断式 ];then 程序 fi 或 if[ 条件判断式 ] then 程序 fi 注:使用fi结尾,和一般语言使用大括号不同;条件判断式使用test命令判断,中括号和条件判断式之间必须有空格;then扣是符合条件之后执行的程序,then可放在[]之后用分号分隔,也可换行写入不写分号 例:#vi fi1.sh #!/bin/bash rate=$(df–h | grep “/dev/sda3” | awk ‘{print $5}’ | cut –d “%” –f 1) if[ “$rate” -ge 80 ] then echo“Warning! /dev/sda3 is full!” fi 》双分支 if [ 条件判断式 ] then 条件成立时执行的程序 else 条件不成立时执行的程序 fi 例:#vi backmysql.sh #!/bin/bash ntpdateasia.pool.ntp.org &>/dev/null date=$(date+%Y%m%d) size=$(du–sh /var/lib/mysql) if[ -d /tmp/dbbak ] then echo“Date: $date!” > /tmp/dbbak/dbinfo.txt cd/tmp/dbbak tar–zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt &>/dev/null rm–rf /tmp/dbbak/dbinfo.txt else mkdir/tmp/dbbak echo“Date: $date!” > /tmp/dbbak/dbinfo.txt echo“Date size: $size” >> /tmp/dbbak/dbinfo.txt cd /tmp/dbbak tar–zcf mysql-lib-$date.tar/gz /var/lib/mysql &>/dev/null rm–rf /tmp/dbbak/dbinfo.txt fi 例:vi autostart.sh #!/bin/bash port=$(nmap–sT 192.168.4.210 | grep tcp | grep http| awk ‘{print $2}’) if [ “$port” == “open” ] then echo“$(date) httpd is OK!” >> /tmp/autostart-acc.log else /etc/rc.d/init.d/httpdstop &>/dev/null /etc/rc.d/init.d/httpdstart &>/dev/null echo“$(date) restart httpd!” >> /tmp/autostart-err.log fi 》多分支 if [ 条件判断式 ] then 当条件判断式1成立时,执行程序1 elif [ 条件判断式 ] then 当条件判断式2成立时,执行程序2 …… else 当所有条件都不成立时,执行此程序 fi 例:#vi if-elif.sh #!/bin/bash read–p “please input a filename: “ file if [ -z “$file” ] then echo“Error,please input a filename.” elif [ ! –e “$file” ] then echo“Your input is not a file” elif [ -f “$file” ] then echo“$file is a regulaar file.” elif [ -d “$file” ] then echo“$file is a directory!” else echo“$file is an other file!” fi 2、多分去case条件语句:case只判断一种条件关系,而if可判断多种条件关系。 case$变量名 in “值1”) 如果变量的值等于值1,则执行程序1 ;; “值2”) 如果变量的值等于值2,则执行程序2 ;; …… *) 如果变量的值都不是以上的值,执行此程序 ;; esac 注:case语句会取出变量中的值,与语句体中的值逐一比较,符合则执行相应程序,不符依次比较下一个值。若所有值都不符合,则执行*)后的程序,*代表所有其它值;以case开头,esac结尾;每个分支之后要用;;结尾,代表该程序段结束。 例:#vi case.sh #!/bin/bash read–p “please chose yes/no: “ cho case$cho in “yes”) echo“Your choose is yes!” ;; “no”) echo“Your choose is no” ;; *) echo“Your choose is error!” ;; esac 3、for循环是固定循环,在循环时已知道要循环几次,也称计数循环 for 变量 in 值1 值2 值3 do 程序 done 注:in后有几个值就循环几次,每次循环都把值赋予变量 for ((初始值;循环控制条件;变量变化)) do 程序 done 注:初始值,在循环开始时需要给变量赋予初始值,如i=1;循环控制条件,用于指定循环的次数,如i<=100;每次循环之后,变量该如何变化,如i=i+1,每次循环之后变量都加1. 例:vi auto-tar.sh #!/bin/bash cd /bin/bash cd /lamp ls *.tar.gz > ls.log for i in $(cat ls.log) do tar -zxf $i &>/dev/null done rm–rf /lamp/ls.log 例:#vi useradd.sh #!/bin/bash read -t 30 -p “Please input username: “ name read -t 30 -p “please input the number of users: “ num read -t 30 -p “please input the password: “ pass if [ -n “$name” –a -n “$num” -a -n “$pass” ] then y=$(echo $num | sed ‘s/[0-9]//g’) if [ -z “$y” ] then for ((i=1;i<=$num;i=i+1)) do /usr/sbin/useradd $name$i &>/dev/null echo $pass | /usr/bin/passwd --stdin $name$i &>/dev/null done fi fi 4、while循环:只要条件判断式成立,循环就一直继续,直到条件不成立才停止。 while[ 条件判断式 ] do 程序 done 5、until循环:条件判断式不成立则进行循环,条件成立,则中止循环。 until[ 条件判断式 ] do 程序 done 6、函数: function 函数名 () { 程序 } 7、特殊流程控制语句: 》exit语句:在脚本中是退出当前脚本,#exit 返回值,返回值可自己定义,用$?查询,若没定义返回值,则是执行exit语句之前最后执行的命令的返回值。 》break语句会结束整个当前循环,而continue语句结束单次当前循环,下次循环会继续 for ((条件判断语句)) do 程序语句 break(continue) 程序语句 done 例:#vi ping.sh #/bin/bash echo “这个脚本是统计/root/ip.txt所有ip地址的丢包率” for i $(cat /root/ip.txt) do aa=$(ping -c 3 $i | grep ttl | wc -l) bb=$(( 3 - $aa )) cc=$(echo “$bb 3” | awk ‘{ print “%5.2f% \n”,$1/$2*100}’) echo “$i的丢包率是:$cc” done
|