Linux Shell编程基础

1.正则表达式

“*”前一个字符匹配0次,或任意多次 
grep "a*" test_rule.txt  
#匹配所有内容,包括空白行
grep "aa*" test_rule.txt 
#匹配至少包含有一个a的行 
grep "aaa*" test_rule.txt  
#匹配最少包含两个连续a的字符串 
grep "aaaaa*" test_rule.txt 
#则会匹配最少包含四个个连续a的字符串

“.” 匹配除了换行符外任意一个字符 
grep  "s..d" test_rule.txt  
#“s..d”会匹配在s和d这两个字母之间一定有两个字符的单词 
grep "s.*d" test_rule.txt  
#匹配在s和d字母之间有任意字符 
grep ".*" test_rule.txt  
#匹配所有内容

“^”匹配行首,“$”匹配行尾 
grep "^M" test_rule.txt 
#匹配以大写“M”开头的行 
grep "n$" test_rule.txt 
#匹配以小写“n”结尾的行 
grep -n "^$" test_rule.txt 
#会匹配空白行 

“[]” 匹配中括号中指定的任意一个字符,只匹配一个字符
grep "s[ao]id" test_rule.txt
#匹配s和i字母中,要不是a、要不是o 
grep "[0-9]" test_rule.txt
#匹配任意一个数字 
grep "^[a-z]" test_rule.txt 
#匹配用小写字母开头的行

“[^]” 匹配除中括号的字符以外的任意一个字符 
grep "^[â-z]" test_rule.txt  
#匹配不用小写字母开头的行 
grep "^[â-zA-Z]" test_rule.txt 
#匹配不用字母开头的行 “\” 转义符 
grep "\.$" test_rule.txt
#匹配使用“.”结尾的行

“\{n\}”表示其前面的字符恰好出现n次 
grep "a\{3\}" test_rule.txt 
#匹配a字母连续出现三次的字符串 
grep "[0-9]\{3\}" test_rule.txt 
#匹配包含连续的三个数字的字符串   

“\{n,\}”表示其前面的字符出现不小于n次 
grep "^[0-9]\{3,\}[a-z]" test_rule.txt 
#匹配最少用连续三个数字开头的行

“\{n,m\}”匹配其前面的字符至少出现n次,最多出现m次 
grep "sa\{1,3\}i" test_rule.txt 
#匹配在字母s和字母i之间有最少一个a,最多三个a

2.字符截取命令

2.1 cut字段提取

cut 与 grep 的区别:cut 提取列 ;grep提取行

[root@localhost ~]# cut [选项] 文件名

选项:

        -f 列号: 提取第几列

        -d 分隔符: 按照指定分隔符分割列

[root@localhost ~]# cut -f 2 student.txt  
#提取第二列
[root@localhost ~]# cut -f 2,3 student.txt  
#提取第二第三列
[root@localhost ~]# cut -d ":" -f 1,3 /etc/passwd
#以:为分隔符提取第一第三列

 cut命令的局限:

区分“ ”会出问题,默认按tab键 制表符分隔

[root@localhost ~]# df -h | cut -d " " -f 1,3
#有空格时提取会出问题

2.2 printf命令

[root@localhost ~]# printf ’ 输出类型输出格式 ’ 输出内容

输出类型:

        %ns : 输出字符串。n是数字指代输出几个字符

        %ni : 输出整数。n是数字指代输出几个数字

        %m.nf : 输出浮点数。m和n是数字,指代输出的整数 位数和小数位数。如%8.2f代表共输出8位数, 其中2位是小数,6位是整数。

输出格式:

        \a : 输出警告声音

        \b : 输出退格键,也就是Backspace键

        \f : 清除屏幕

        \n : 换行

        \r : 回车,也就是Enter键

        \t : 水平输出退格键,也就是Tab键

        \v : 垂直输出退格键,也就是Tab键

[root@localhost ~]# printf %s 1 2 3 4 5 6  
[root@localhost ~]# printf %s %s %s 1 2 3 4 5 6  
[root@localhost ~]# printf  '%s %s %s' 1 2 3 4 5 6  
[root@localhost ~]# printf '%s %s %s\n' 1 2 3 4 5 6 
tips:printf  '%s %s %s\n' 1 2 3 4 5 6 
三个看成一个整体所以123是一个整体,456是另一个。所以在3后面换行

 

printf  '%s' $(cat student.txt) 
#不调整输出格式  

 

 [root@localhost ~]# printf '%s\t%s\t%s\t%s\t\n' $(cat student.txt)
# 调整格式输出

 在awk命令的输出中支持print和printf命令

        print:print会在每个输出之后自动加入一个换行符(Linux默认没有print命令)

        printf:printf是标准格式输出命令,并不会自动加入换行符,如果需要换行,需要手工加入换行符

2.3 awk命令

[root@localhost ~]# awk ‘条件1{动作1} 条件2{动作2}…’ 文件名

条件(Pattern):

        一般使用关系表达式作为条件

        x > 10 判断变量 x是否大于10

        x>=10 大于等于

        x<=10 小于等于

动作(Action):

        格式化输出

        流程控制语句

[root@localhost ~]# df -h | awk '{print $1 "\t" $3}'    

 提取已用百分比

[root@localhost ~]# df -h | grep centos | awk '{print $5}' | cut -d"%" -f1

BEGIN

BEGIN 模式用于在 AWK 开始处理输入之前执行一次性的初始化操作。

#awk 'BEGIN{printf "This is a transcript \n" }  {printf $2 "\t" $6 "\n"}' student.txt

END

END 模式用于在 AWK 处理完所有输入之后执行一次性的收尾操作。

# awk 'END{printf "The End \n" }                             
{printf $2 "\t" $6 "\n"}' student.txt  

FS内置变量

定义分隔符 

#cat /etc/passwd | grep "/bin/bash" | awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'

 关系运算符

#cat student.txt | grep -v Name |  awk '$6 >= 87 {printf $2 "\n" }'

2.4 sed命令

sed 是一种几乎包括在所有 UNIX 平台(包括 Linux)的轻量级流编辑器。sed主要是用来将数据进行选取、替换、删除、新增的命令。

[root@localhost ~]# sed [选项] ‘[动作]’ 文件名

选项:

        -n: 一般sed命令会把所有数据都输出到屏幕 , 如果加入此选择,则只会把经过 sed命令处理的行输出到屏幕。

        -e: 允许对输入数据应用多条sed命令编辑

        -i: 用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出

动作:

        a \: 追加,在当前行后添加一行或多行。添加多行时,除最后一行外,每行末尾需要用“\”代表数据未完结。

        c \: 行替换,用c后面的字符串替换原数据行,替换多行时,除最后一行外,每行末尾需“\”代表数据未完结。

        i \: 插入,在当期行前插入一行或多行。插入多行时,除最后一行外,每行末尾需要“\”代表数据未完结。

        d: 删除,删除指定的行。

        p: 打印,输出指定的行。

        s: 字串替换,用一个字符串替换另外一个字符串。格式为“行范围s/旧字串/新字串/g”(和vim中的替换格式类似)。

[root@localhost ~]# sed '2p' student.txt  
#查看文件的第二行  
[root@localhost ~]# sed -n '2p' student.txt    
[root@localhost ~]# sed '1,2d' student.txt  
#删除第一行到第二行的数据,但不修改文件本身

 ​​​

[root@localhost ~]# sed '2a hello' student.txt   
#在第二行后追加hello
# a : 追加
  
[root@localhost ~]# sed '2i hello \ world' student.txt 
#在第二行前插入两行数据
# i : 当前行前一行插入 

# sed '2c No such person‘ student.txt 
#数据替换
# c :行替换 用c后面的字符替换原数据行
字符串替换

# sed ‘s/旧字串/新字串/g’ 文件名

# sed '3s/74/99/g' student.txt  
#在第三行中,把74换成99 

#sed -i '3s/74/99/g' student.txt  
#sed操作的数据直接写入文件  
# -i 修改写入文件

# sed -e 's/Liming//g ; s/Gao//g' student.txt  
#同时把“Liming”和“Gao”替换为空
# -e 多条件

 3.字符处理命令

3.1 排序命令 sort

[root@localhost ~]# sort [选项] 文件名

选项:

        -f: 忽略大小写

        -n: 以数值型进行排序,默认使用字符串型排序

        -r: 反向排序

        -t: 指定分隔符,默认是分隔符是制表符

        -k n[,m]: 按照指定的字段范围排序。从第n字段开始, m字段结束(默认到行尾)

[root@localhost ~]# sort /etc/passwd 
#排序用户信息文件  

[root@localhost ~]# sort -r /etc/passwd 
#反向排序

[root@localhost ~]# sort -t ":" -k 3,3 /etc/passwd 
#指定分隔符是“:”,用第三字段开头,第三字段结尾排序,就是只用第三字段排序  

[root@localhost ~]# sort -n -t ":" -k 3,3 /etc/passwd

4.条件判断 

4.1 按文件类型

 两种判断格式

[root@localhost ~]# test -e /root/install.log

[root@localhost ~]# [ -e /root/install.log ]

[ -d /root ] && echo "yes" || echo "no"  
#第一个判断命令如果正确执行,则打印“yes”,否则打印“no”

4.2 按文件权限

[ -w student.txt ] && echo "yes" || echo "no"                   
#判断文件是拥有写权限的

缺陷:不支持分组查看,有拥有的就返回true 

4.3 比较两个文件

ln /root/student.txt /tmp/stu.txt 
#创建个硬链接吧 

[ /root/student.txt -ef /tmp/stu.txt ] && echo "yes" || echo "no" yes 
#用test测试下,果然很有用
# inode号一致

4.4 比较两个整数

[ 23 -ge 22 ] && echo "yes" || echo "no"                                   yes 
#判断23是否大于等于22,当然是了  
[ 23 -le 22 ] && echo "yes" || echo "no"                                   no 
#判断23是否小于等于22,当然不是了

4.5 字符串判断

name=sc 
#给name变量赋值 
[ -z "$name" ] && echo "yes" || echo "no"  
no 
#判断name变量是否为空,因为不为空,所以返回no  

aa=11 
bb=22 
#给变量aa和变量bb赋值 
[ "$aa" == "bb" ] && echo "yes" || echo "no"            
no 
#判断两个变量的值是否相等,明显不相等,所以返回no

4.6 多条件判断

aa=11 
[ -n "$aa"  -a "$aa" -gt 23 ] && echo "yes" || echo "no" 
no 
#判断变量aa是否有值,同时判断变量aa的是否大于23 
#因为变量aa的值不大于23,所以虽然第一个判断值为真,返回的结果也是假  

aa=24 
[ -n "$aa"  -a "$aa" -gt 23 ] && echo "yes" || echo "no" yes

5.流程控制

5.1 if语句

5.1.1 单分支if条件语句

if  [ 条件判断式 ] ; then
程序 
fi 
 
#或者

if  [ 条件判断式 ]  
    then
        	程序 
fi 

单分支条件语句需要注意几个点

  • if语句使用fi结尾,和一般语言使用大括号结尾不同

  • [ 条件判断式 ]就是使用test命令判断,所以中括号和条件判断式之间必须有空格

  • then后面跟符合条件之后执行的程序,可以放在[]之后,用“;”分割。也可以换行写入,就不需要“;”了

#!/bin/basn
# 统计根分区使用率 
# Author: shenchao (E-mail: shenchao@qq.com) 
 
 rate=$(df -h | grep "/dev/sda3" | awk '{print $5}' | cut -d "%" -f 1)  
 # 把根分区使用率作为变量值赋予变量rate
  
 if [ $rate -ge 80]
    then
        echo "Warning! /dev/sda3 is full!"
 fi

5.1.2 双分支if条件语句

if [ 条件判断式 ] 
    then   
        条件成立时,执行的程序  
    else 
        条件不成立时,执行的另一个程序 
fi

 例子1:备份mysql数据库

#!/bin/bash
#备份mysql数据库。

# Author:shenchao(E-mail:shenchao@lampbrother.net)

ntpdateasia.pool.ntp.org&>/dev/null
#同步系统时间

date=$(date+%y%m%d)
#把当前系统时间按照“年月日”格式赋予变量

datesize=$(du-sh/var/lib/mysql)
#统计mysql数据库的大小,并把大小赋予size变量

if [ -d/tmp/dbbak ]
    then
        echo"Date:$date!" > /tmp/dbbak/dbinfo.txt
        echo"Datasize$size">>/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"Datasize:size">>/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
 fi

 例子2:判断apache是否启动

#!/bin/bash
#Author:shenchao(E-mail:shenchao@lampbrother.net)

port=$(nmap -sT 192.168.1.156 | grep tcp | grep http |awk'{print$2}')
#使用nmap命令扫描服务器,并截取apache服务的状态,赋予变量port

if [ "$port"=="open" ]
    then
        echo“$(date)httpdisok!” >> /tmp/autostart-acc.log
    else
        /etc/rc.d/init.d/httpdstart &> /dev/null
        echo"$(date)restarthttpd!!" >> /tmp/autostart-err.log
fi

5.1.3 多分支if条件语句

if [ 条件判断式1 ]
    then
        当条件判断式1成立时,执行程序1
elif [ 条件判断式2 ]
    then
        当条件判断式2成立时,执行程序2
„省略更多条件…
else
    当所有条件都不成立时,最后执行此程序
fi
#!/bin/bash
#判断用户输入的是什么文件

#Author:shenchao(E-mail:shenchao@lampbrother.net)

read-p"Pleaseinputafilename:"file
#接收键盘的输入,并赋予变量file

if [ -z "$file" ]
#判断file变量是否为空       
    then
        echo "Error,pleaseinputafilename"
        exit 1
elif [ ! -e "$file" ]
#判断file的值是否存在
    then
        echo "Yourinputisnotafile!"
        exit 2
elif [ -f "$file" ]
#判断file的值是否为普通文件
    then 
    echo "$fileisaregularefile!"
elif [ -d "$file" ]
#判断file的值是否为目录文件  
    then
        echo "$fileisadirectory!"
else
    echo"$fileisanotherfile!"
fi

5.2 case语句

多分支case条件语句

  • case语句和if…elif…else语句一样都是多分支条件语句,不过和if多分支条件语句不同的是,case语句只能判断一种条件关系,而if语句可以判断多种条件关系。

    case $ 变量名 in  
        " 值1")   
             如果变量的值等于值1,则执行程序1   
            ; ;
         " 值2")   
             如果变量的值等于值2,则执行程序2  
              ; ;  
          …省略其他分支…  
          * )   
          如果变量的值都不是以上的值,则执行此程序 
          ; ;
    esac 
    
    #!/bin/bash
    #判断用户输入
    
    #Author:shenchao(E-mail:shenchao@lampbrother.net)
    
    read -p"Pleasechooseyes/no:" -t 30 cho
    case $cho in
        "yes")
            echo"Yourchooseisyes!"
            ;;       
        "no")
            echo"Yourchooseisno!"
            ;;
        *)
        echo"Yourchooseiserror!"
        ;;
    esac
    

5.3 for循环

语法一

for 变量 in 值1 值2 值3
    do 
        程序
    done
#!/bin/bash
for city in beijing nanjing shanghai 
    do
        echo "this city is $city "
    done 

 输出:

this city is beijing

this city is nanjing

this city is shanghai

#!/bin/bash
#批量解压缩脚本

cd /sh
ls *.tar.gz -> ls.log
for i in $(cat ls.log)
    do
       tar -zxf $i &> /dev/null
    done 
rm -rf /sh/ls.log

语法二

for((初始值;循环控制条件;变量变化))
    do
        程序
    done
#!/bin/bash
#从1加到100


num=0
for((i=1;i<=100;i++))
    do
        num=$(($num+$i))
    done
echo "this sum of 1+2+...+100 is: $num"

5.4 while循环和until循环

5.4.1 while循环

while循环是不定循环,也称作条件循环。只要条件判断式成立,循环就会一直继续,直到条件判断式不成立,循环才会停止。这就和for的固定循环不太一样了。

while [ 条件判断式 ]
    do
        程序
    done
#!/bin/bash
#从1加到100
#Author:shenchao(E-mail:shenchao@lampbrother.net)
i=1
s=0
while [ $i -le 100 ] 
#如果变量i的值小于等于100,则执行循环
    do
        s=$(($s+$i))
        i=$(($i+1))
    done
echo"Thesumis:$s"

5.4.2 until循环

until循环,和while循环相反,until循环时只要条件判断式不成立则进行循环,并执行循环程序。一旦循环条件成立,则终止循环。

until [ 条件判断式 ]
    do
        程序
    done
#!/bin/bash
#从1加到100
#Author:shenchao(E-mail:shenchao@lampbrother.net)
i=1
s=0
until [ $i -gt 100 ]
#循环直到变量i的值大于100,就停止循环
    do
        s=$(($s+$i))i=$(($i+1))
    done
echo"Thesumis:$s"

6.函数

语法:

[ function ] funname [()]{
    action;
    [return int;]
}

[]   表示可以省略

tips:在以上的函数语法中,前面的funcation 表示声明一个函数!!! 可以不写 return -n 是指退出函数

#!/bin/bash
funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"return $(($aNum+$anotherNum))}
funWithReturn
echo "输入的两个数字之和为 $? !"

 输出:

[timo@local1 sh]$ sh function.sh 
这个函数会对输入的两个数字进行相加运算...
输入第一个数字: 
12
输入第二个数字: 
22
两个数字分别为 12 和 22 !
输入的两个数字之和为 34 !

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值