shell 脚本基础(四十三)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

       今天学习的是Shell脚本的编写,Shell脚本是一种编写在Unix或类Unix操作系统上的脚本程序,用于执行一系列的命令。它由一系列的命令和控制结构组成,可以通过直接在命令行中输入脚本名称来执行,也可以通过给脚本文件添加执行权限后直接运行该文件。

Shell脚本通常用于自动化任务,可以编写一些简单或复杂的脚本来执行重复性的工作,提高工作效率。它可以像编程语言一样实现流程控制、变量定义、函数调用等功能。Shell脚本可以用多种脚本语言编写,如Bash、Csh、Ksh等,其中Bash是最常用的脚本语言。

使用Shell脚本可以实现很多任务,比如文件处理、系统管理、数据处理等。它可以调用系统命令、执行外部程序、处理输入输出、控制进程等。Shell脚本的优点是简单易学、灵活性强,但在处理大规模任务和复杂逻辑时可能效率较低,适用于快速编写和执行一些小规模任务。


提示:以下是本篇文章正文内容,下面案例可供参考

一、概述

1. 概念

脚本就是将手动一次性执行的命令进行规范且自动化

2. 学习路径

 2.1表达式

    变量预定义变量
位置变量
自定义变量
    运算符数学运算
 数值比较
 字符串比较
文件判断
布尔运算符

 2.2 语句

条件语句 if
 分支语句   case
循环语句for
 while

 2.3 函数

函数:函数是以函数名()跟{}括起来的内容组成。函数可以实现一些功能封装,同时函数也支持与脚本类似的参数解析逻辑。

2.4 正则表达式

        标准正则
        扩展正则

2.5 文件操作四剑客

         find
        egrep
        sed
        awk

二、表达式

1.shell

shell命令解释环境
    类型
        sh
        ash
        bsh
        csh
        bash
        tcsh
        dsh
        zsh
    查看系统中支持的shell
        cat /etc/shells


    查看系统默认shell
        echo $SHELL

 2.表达式

2.1 变量

2.2.1组成
变量名不会变化杯子
容器...
声明规范不能是数字或数字开头
以_或字母开头
变量名中不能包含特殊字符
声明方法驼峰式userName
双驼峰UserName
shell写法user_name
username
USERNAME
变量值不断变化承载的物体
数字、字符
 2.2.2 类型
系统内置变量(环境变量)   env

自定义变量 varName=varValue
       等号两边不能有格
     数字 var1=1
字符串 shell中可以不使用引号
当包含有空格时,需要使用引号
引号的用法 不会引用变量值    单引号    '
     会应用变量值 双引号     "
    引用命令结果 反撇号   `
     $(命令)   应用场景较多
    位置变量脚本后参数所在的位置
 $1
 ...
    $9
 预定义变量     $0    脚本本身的名称
     $# 脚本后参数的个数
     $* 脚本运行时参数的内容(整体输出)
     $@ 脚本运行时参数的内容(逐个输出)
     $? 脚本运行完毕后的返回值
 默认情况   0           成功
  非0         失败

                    

2.2.3 作用域

    默认变量只在当前shell下生效
    若要在当前及其子shell下生效,需要声明为全局变量
        export

2.2.4 输出

echo $varName

2.2.5 shell中的字符串

 string
    赋值: str1=foodfornoting.gpg
    (1)获得字符串的长度
    语法:    ${#StringName}
    案例:    echo ${#str1}
    输出结果:17
    (2)字符串取子串
    语法:    ${#StringName:position:lenght}
    案例:    echo ${str1:0:3}
    输出结果:foo
    注意:lenght没有定义时,一直取到字符串的结尾!
    (3)字符串的截取
    a)从左至右截取最后一个匹配字符串string之后的所有字符串
    语法:    ${StringName##*string}
    案例:    echo ${str1##*fo}
    输出结果:rnoting.gpg
    b)从左至右截取第一个匹配字符串string之后的所有字符串
    语法:    ${StringName#*string}
    案例:    echo ${str1#*fo}
    输出结果:odfornoting.gpg
    c)从右至左截取最后一个匹配字符串string之后的所有字符串
    语法:    ${StringName%%string*}    
    案例:    echo ${str2%%o*}
    输出结果:f
    d)从右至左截取第一个匹配字符串string之后的所有字符串
    语法: ${StringName%string*}
    案例: echo ${str2%o*}
    输出结果:foodforn
    (4)字符串的拼接
    语法:    StringName3=${StingName1}${StringName2}
    案例:    str1=Hello
        str2=,Jack!
        str3=${str1}${str2}
        echo ${str3}
    输出结果: Hello,Jack!
    (5)字符串替换:
    语法:    ${StringName/OldString/NewString}
    案例:    str1=foodfornoting.gpg
        echo ${str1/oo/kk}
    输出结果:fkkdfornoting.gpg

2.2 运算符

数学运算

数学运算+ - * / %* 作为乘号时需要加转义符\
运算方法exprexpr $a + $b
$((a+b))echo $((a+b))
$[a+b]echo $[a+b]
注意
  
 shell不支持浮点数的显示

比较运算

条件测试test var1 比较符 var2
[ var1 比较符 var2 ]
&&[ $a -ne $b ] &&  echo OK条件 && 输出结果
条件为真输出
||[ $a -ne $b ] ||  echo OK条件 || 输出结果
条件为假输出

数值比较

-eq等于
-ne不等于
-lt小于
-le小于等于
-gt大于
-ge大于等于

字符串比较

=字符串一致
!=字符串不一致
-z字符串为空
! -z 字符串不为空

文件比较

-e文件或目录是否存在
-f是否为文件
-d是否为目录
-r判断文件是否可读
-w判断文件是否可写
-x判断文件是否可执行

逻辑运算符

&&-a并且,有假则假,全真为真[ -r 111 -a -w 111 -a -x 111 ]
[ -r 111 ] && [ -w 111 ] &&  [ -x 111 ]
 [ -x /root/file1 -a  -d /root/file1 ]
 [ -x /root/file1 ]  && [ -d /root/file1 ]
||-o或者,有真则真,全假为假
取反有真则假,有假则真

2.3 shell脚本编写规范

     第一行
        #!/bin/bash
    第二行
        #脚本的说明
    第三行
        脚本正文

2.4 shell运行规则

没有x权限bash  脚本所在路径/脚本文件
source 脚本所在路径/脚本文件          脚本存在cd  时,会切换到目标目录
.      脚本所在路径/脚本文件
有x权限./脚本文件
脚本绝对路径/脚本文件

shell脚本运行追踪
    bash -x 脚本所在路径/脚本文件

$[$RANDOM%100]
    返回100内随机数

seq 1 10
    返回1到10 的连续数字

{1..10}
    返回1到10 的连续数字

seq 1.1 10.1
    返回1.1 2.1 3.1.... 10.1

read -p "提示语" 变量名
    读取键盘输入并赋值给变量名

2.5 语句

2.5.1 条件语句

单分支if
        if [ ];then
fi
    双分支if
        if [ ];then
else
fi
    多分支if
        if [ ];then
elif [ ];then
else
fi

2.5.2 循环语句

  for
        for 条件(i in 值)|((i=1;i<=10;i++))
do
    语句
done
    while
        i=1
while 条件
do
    语句
    let  i++
done
    关于$*与$@的验证

2.5.3 开关语句

  case
        case $1 in
条件1)
    语句
;;
条件2)
    语句
;;
*)
    帮助信息
;;
esac
    nginx启动脚本

2. 文件操作四剑客

2.1 正则表达式

2.1.1 基础正则

    a)查找特定字符
        cat test.txt | grep -n 'was'


    b)利用[]查找集合字符
        cat test.txt | grep -n 'sh[io]rt'
            匹配i或者o


        cat test.txt | grep -n '[^w]'
            排除w


        cat test.txt | grep -n '[a-h]oo'


        cat test.txt | grep -n '[0-9]'

     c)查找行首"^"与行尾"$" 
        cat test.txt | grep -n '^[A-Z]'


        cat test.txt | grep '\.$'
            \ 为转义符
    d)查找任意一个字符"."与重复字符"*"
        cat test.txt | grep -n 'w..d'


        cat test.txt | grep -n 'ooo*'


    e)查找连续的字符范围"{}",需要使用转义符,"\{\}"
        cat test.txt | grep -n 'o\{2\}'


        cat test.txt | grep -n 'wo\{2,5\}d'


        cat test.txt | grep -n 'wo\{2,\}d'

 

2.1.2 扩展正则

    a)+,重复一个或一个以上的前一个字符
        cat test.txt | grep -nE 'wo+d' 或者
        cat test.txt | egrep -n 'wo+d'


    b)?,零个或者一个前一个字符
        cat test.txt | egrep -n 'bes?t'


    c)|,使用或者的方式找出多个字符
        cat test.txt | egrep -n 'of|is|on'


    d)(),查找组字符串
        cat test.txt | egrep -n 't(a|e)st'


    e)()+,辨别多个重复的组
        cat test.txt | egrep -n 'A(xyz)+C' 

2.1.3 常见正则表达式

数字
        “^[0-9]*[1-9][0-9]*$” //正整数  
        “^((-\d+)|(0+))$” //非正整数(负整数 + 0)  
        “^-[0-9]*[1-9][0-9]*$” //负整数  
        “^-?\d+$” //整数 
        “^\d+(\.\d+)?$” //非负浮点数(正浮点数 + 0)  
        “^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$” //正浮点数 
        “^((-\d+(\.\d+)?)|(0+(\.0+)?))$” //非正浮点数(负浮点数 + 0) 
        “^(-?\d+)(\.\d+)?$” //浮点数 
字符串
        “^[A-Z]+$” //由26个英文字母的大写组成的字符串  
        “^[a-z]+$” //由26个英文字母的小写组成的字符串  
        “^[A-Za-z0-9]+$” //由数字和26个英文字母组成的字符串  
        “^\w+$” //由数字、26个英文字母或者下划线组成的字符串

 Email
        “^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$” //email地址  
        “^([w-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([w-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$”                         //Email 

Url 
        “^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$” //url 

IP
        “^(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5]).(d{1,2}|1dd|2[0-4]d|25[0-5])$”   //IP地址

Tel 
        /^((\+?[0-9]{2,4}\-[0-9]{3,4}\-)|([0-9]{3,4}\-))?([0-9]{7,8})(\-[0-9]+)?$/     //电话号码

日期校验
           /^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$/   //  年-月-日    yyyy-MM-dd /                    yy-MM-dd 格式
           "^[0-9]{4}-((0([1-9]{1}))|(1[1|2]))-(([0-2]([0-9]{1}))|(3[0|1]))$"   // 年-月- 日  yyyy-MM-dd 格式
          /^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$/   // 月/日/年

2.2 grep进阶

  选项
        -r
            递归扫描指定目录下的每一个文件
        -l
            只显示匹配到指定关键字的文件名,而不是文件内容
    案例
        查看/etc目录下所有包含bash的文件名
        grep -rl bash /etc

 egrep
    完美支持正则表达式

2.3 find进阶

    按照权限查找
        -perm
    按照时间戳查找
        -atime
        -mtime
        -ctime
    -exec
        find /var/spool/mail -type f -exec rm -rf {} \;
    xargs
        find /var/spool/mail -type f | xargs rm -rf

2.4 sed

语法
    sed [选项] '操作' 参数 
    sed [选项] -f scriptfile 参数

选项

-e

表示用指定命令或脚本处理

-f指定脚本文件
-h帮助
-n表示仅显示处理后的结果
-i直接编辑文本文件
-r支持扩展正则

操作

a增加,在当前行下面以行增加指定内容
c替换,将选定行替换
d删除,删除指定行
i插入,在选定行的上面插入一行
p打印
s替换,替换成指定字符
y字符转换

案例
    1.输出符合条件的文本:
        sed -n 'p' test.txt     #相当于cat


        sed -n '3p' test.txt    #打印第3行


        sed -n '3,6p' test.txt    #打印第3到6行的内容


        sed -n 'p;n' test.txt    #打印奇数行 
        sed -n 'n;p' test.txt    #打印偶数行


        sed -n '1,6{p;n}' test.txt    #打印1到6行之间的奇数行


        sed -n '5,${p;n}' test.txt    #从第5行开始打印奇数行


        sed -n '/goo/p' test.txt    #匹配goo 


        sed -n '5,/goo/p' test.txt     #匹配从第5行开始到包含goo的行


        sed -n '/goo/,10p' test.txt     #匹配从包含goo的行到第10行结束


        sed -n '/the/=' test.txt    #打印包含the的行号


    2.删除符合条件的文本
        nl test.txt | sed '3d'    #删除第3行 
        nl test.txt | sed '3,5d'


        nl test.txt | sed '/the/d'    #删除the所在行


    3.替换符合条件的文本
        nl test.txt | sed 's/the/TTTTTT/'    #替换全文本


        nl test.txt | sed '3s/good/TTTTTT/'    #替换第4行


        nl test.txt | sed 's/l/L/2'        #替换匹配到的第2个l


    4.迁移符合条件的文本
        H:复制;g:覆盖;G:追加行;w:保存;r:读取;a:追加内容
        sed '/the/{H;d};$G' test.txt #匹配the所在行并迁移至文件末尾
        sed '3aTest' test.txt #在第3行下面新建行并写入Test
        sed '/the/aTest' test.txt #匹配the所在行并在下一行写入Test
    5.使用脚本编辑文件内容
        vim opt.txt
        1,5H
        1,5d
        16G
        sed -f opt.txt test.txt    #将1到5行迁移至16行后
    6.以上修改想要直接修改文本源文件,只需要加入选项"-i"

2.5 awk

语法
    awk 选项 '模式或条件{编辑命令}' 文件1 文件2 ...
    awk -f 脚本文件 文件1 文件2 ...

选项
    -F
        指定每行的分隔符
        默认分隔符为空格

内建变量

FS指定每行的分隔符
NF指定当前处理行的字段个数
NR当前处理行的行号
$0当前处理行的整行内容
$n当前处理的第n个字段
FILENAME处理文件名
RS数据记录分割,默认是\n

案例:
    a)按行输出
        awk '{print}' test.txt          #等同cat 


        awk 'NR>=1&&NR<=3{print}' test.txt 


        awk 'NR==1,NR==3{print}' test.txt #打印1到3行

        awk 'NR%2==0{print}' test.txt     #打印偶数行


    b)按段输出
        默认以"空格"分段!
        ifconfig ens33 |awk '/netmask/{print $2}' #筛选IP地址
        cat /etc/shadow | awk -F : '$2=="!!"{print $1}' #打印不能登录系统的用户
    c)调用shell命令
        cat /etc/passwd | awk -F : '/bash$/{print | "wc -l"}' /etc/passwd     #统计能够登录系统的用户个数       


 总结

Shell脚本是一种文本文件,由一系列命令和控制结构组成,用于执行一系列的任务。

Shell脚本可以通过直接在命令行中输入脚本名称来执行,也可以通过给脚本文件添加执行权限后直接运行该文件。

Shell脚本可以用多种脚本语言编写,如Bash、Csh、Ksh等,其中Bash是最常用的脚本语言。

Shell脚本可以调用系统命令、执行外部程序、处理输入输出、控制进程等。

Shell脚本可以实现文件处理、系统管理、数据处理等多种任务。

Shell脚本具有简单易学、灵活性强的特点,适用于快速编写和执行一些小规模任务。

Shell脚本的效率可能较低,适用于处理小规模任务和简单逻辑,对于大规模任务和复杂逻辑,可能效率较低。

Shell脚本是Unix系统中常用的自动化工具,广泛应用于系统管理、软件开发等领域。

总而言之,Shell脚本是一种简单、灵活的自动化工具,能够帮助我们自动化执行任务,提高工作效率。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值