zoukankan      html  css  js  c++  java
  • 03 元字符及运算符

    元字符

    元字符指的是能够被shell解释的特殊字符,每个特殊字符都有其特殊含义,这些字符一方面可用于变量值的运算、我们可以称之为运算符,另外一方面可以和shell命令配合使用来达到更高级的效果

    算数运算符

    运算符

    /
    %

    算数运算符需要配合下述操作使用

    # 浮点运算
    bc  
    
    # 整数运算
    expr
    $(())
    $[]
    let
    

    详解如下

    • 1、bc是比较常用的linux计算工具了,而且支持浮点运算

      [root@localhost ~]# res=`echo 1+1 | bc`
      [root@localhost ~]# echo $res
      2
      
      [root@localhost ~]# res=`echo 10 % 3 | bc`
      [root@localhost ~]# echo $res
      1
      
      [root@localhost ~]# res=`echo 1.2+1.3|bc`
      [root@localhost ~]# echo $res
      2.5
      
      [root@localhost ~]# res=`echo 5.0+3.0|bc`
      [root@localhost ~]# echo $res
      8.0
      
      [root@localhost ~]# res=`echo "scale=2;5.0/3.0"|bc`
      [root@localhost ~]# echo $res
      1.66
      
      [root@localhost ~]# res=`echo "scale=2;5.0/6.0"|bc`
      [root@localhost ~]# echo $res
      .83
      
    • 2、expr不支持浮点数计算。而且要注意数字与运算符中的空格

      [root@localhost ~]# res=`expr 5 / 3` # 不支持浮点计算
      [root@localhost ~]# echo $res
      1
      
      [root@localhost ~]# res=`expr 1+1` # 注意:要有空格
      [root@localhost ~]# echo $res
      1+1
      [root@localhost ~]# res=`expr 1 + 1`
      [root@localhost ~]# echo $res
      2
      
      如果是乘法,如需要转义*
      [root@egon ~]# expr 3 * 10
      30
      
    • 3、$(()) 同expr,不支持浮点数运算

      # 例如:
      [root@localhost ~]# echo $((1+1))
      2
      [root@localhost ~]# echo $((1.0+2.0)) # 不支持浮点运算符
      -bash: 1.0+2.0: 语法错误: 无效的算术运算符 (错误符号是 ".0+2.0")
      
      # 注意:
      echo $(($num1+$num2)) # 也可以简写为 echo $((num1+num2))
      echo $(((5-3)*2)) # 可以嵌套括号
      
    • 4、$[]同expr以及$(()),不支持浮点运算

      [root@egon ~]# echo $[$num1+$num2] # 等同于 echo $[num1+num2]
      333
      [root@egon ~]# echo $[1.3+3.1]
      -bash: 1.3+3.1: 语法错误: 无效的算术运算符 (错误符号是 ".3+3.1")
      
    • 5、let 不支持浮点数运算,而且不支持直接输出,只能赋值

      [root@localhost ~]# let res=1+1
      [root@localhost ~]# echo $res
      2
      [root@localhost ~]#
      [root@localhost ~]# let res=50/5
      [root@localhost ~]# echo $res
      10
      [root@localhost ~]# let c=1.3*3
      -bash: let: c=1.3*3: 语法错误: 无效的算术运算符 (错误符号是 ".3*3"
      
    • 6、强调:整数与非整数之间运算会报错

      [root@egon ~]# expr 1 + a
      expr: 非整数参数
      [root@egon ~]# expr 1 + 1.3
      expr: 非整数参数
      

    练习题

    # 脚本案例: 编写判断输入参数是否是整数信息脚本
    #!/bin/bash
    
    a=$1
    expr $a + 0 &>/dev/null  # 只有整型加0才不会报错,浮点数及字符与0详解都会报错
    [ $? -eq 0 ] && echo "输入的是整数信息" || echo "输入的是非整数信息"
    
    # 如何利用脚本计算1+2+3+4..10总和数值
    方法一:
    seq -s "+" 10|bc
     
    方法二:
    echo {1..10}|tr " " "+"|bc
     
    方法三:
    awk 'BEGIN{for (i=1; i<=10; i++) a=a+i; print a}'
    

    测试运算符

    测试命令:test,详细可用man test查询

    测试符号:[],注意只有一层中括号,中括号内左右两侧必须要有空格

    test与[]效果都一样,参数也都一样

    2.1 测试文件状态

    参数 含义
    -d 目录是否存在
    -s 文件长度是否大于0
    -f 是否为标准文件
    -w 可写
    -r 可读
    -x 可执行
    -L 符号连接
    -u 文件有suid 位设置
    -c 判断是否为磁盘文件

    2.2 字符串测试

    符号 含义
    == 两个字符串相等
    != 两个字符串不相等
    -z 字符串长度为零
    -n 字符串长度不为零

    2.3 测试数值

    test与[]也可以测试数值,与 [[]]和(())效果一样,下一小节会详细介绍[[]]和(())

    参数 含义
    -eq (=) 等于则为真
    -ne (!=) 不等于则为真
    -gt (>) 大于则为真
    -ge (>=) 大于等于则为真
    -lt (<) 小于则为真
    -le (<=) 小于等于则为真
    • -a并且

    • -o或者

    关系运算符

    <

    >

    <=

    >=

    ==

    !=

    &&

    ||

    上述关系运算符需要配合(())使用(注意(())属于C语言风格的比较),最终都是用来当if判断或者while循环的条件

    [root@egon ~]# x=100
    
    [root@egon ~]# (($x>10))
    [root@egon ~]# echo $?
    0
    
    [root@egon ~]# (($x < 10));echo $?
    1
    
    [root@egon ~]# (($x == 100));echo $?
    0
    
    [root@egon ~]# (($x != 100));echo $?
    1
    
    [root@egon ~]# (($x != 100)) && (("egon" == "egon"))
    [root@egon ~]# echo $?
    1
    
    [root@egon ~]# (($x != 100)) || (("egon" == "egon"))
    [root@egon ~]# echo $?
    0
    
    [root@egon ~]# (($x != 100 && "egon" == "egon"));echo $?
    1
    
    [root@egon ~]# (($x != 100 || "egon" == "egon"));echo $?
    0
    
    

    赋值运算符

    • =
      [root@egon ~]# x=10
      [root@egon ~]# echo $x
      10
    • +=
      [root@egon ~]# x=10
      [root@egon ~]# ((x%3))
      [root@egon ~]# echo $x
      10
      [root@egon ~]# ((x%=3))
      [root@egon ~]# echo $x
      1
    • *=
      同上
    • /=
      同上
    • %=
      同上

    补充

    5.1 补充[[]]

    [[]]与[]基本一样,不同的是[[]]支持正则匹配,不过要注意的是必须在内层中括号内左右两侧加空格

    [root@egon ~]# [[ "$USER" ==  "root" ]];echo $?  # 注意内层[]中包含的内容必须左右两侧加空格
    0
    [root@egon ~]# [[ "$USER" ==  "root" ]];echo $?  # 一个等号也行两个等号也可以额
    0
    
    
    
    # 此外[[]]内部是可以使用正则的,注意:正则表达式不要加引号
    [root@egon ~]# [[ "$USER" =~ "^root$" ]];echo $?  # 正则表达式不要加引号
    1
    [root@egon ~]# [[ "$USER" =~ ^root$ ]];echo $?  # 正则表达式不要加引号
    0
    [root@egon ~]# [[ ! "$USER" =~ t$ ]] && echo 此时不是管理员登录 || echo 是管理员登录
    是管理员登录
    
    
    
    [root@egon ~]# num1=123
    [root@egon ~]# [[ "$num1" =~ ^[0-9]+$ ]];echo $?  # 判断是否是数字
    0
    [root@egon ~]# [[ "$num1" =~ ^[0-9]+$ ]] && echo "是数字"
    是数字
    
    
    
    [root@egon ~]# num2=abc123de
    [root@egon ~]# [[ "$num2" =~ ^[0-9]+$ ]];echo $?
    1
    [root@egon ~]# [[ "$num2" =~ ^[0-9]+$ ]] || echo "num2不是数字"
    num2不是数字
    

    企业面试题1: 传入两个数值信息, 自动让脚本显示数值比较情况

    [root@egon shell]# cat num.sh 
    #!/bin/bash
    
    [ $# -ne 2 ] && echo "只能传入两个整数" && exit
    [[ ! $1 =~ ^[0-9]+$ ]] && echo "参数1必须是整数" && exit
    [[ ! $2 =~ ^[0-9]+$ ]] && echo "参数2必须是整数" && exit
    
    [[ $1 -lt $2 ]] && echo "$1 < $2"
    [[ $1 -gt $2 ]] && echo "$1 > $2"
    [[ $1 -eq $2 ]] && echo "$1 = $2"
    [root@egon shell]# chmod +x num.sh 
    [root@egon shell]# ./num.sh 17 37
    17 < 37
    

    5.2 补充浮点数的比较

    # 需要注意的是:bc的结果为1代表真,为0代表假
    [root@egon ~]# echo "10.3 >= 10.1" | bc
    1
    [root@egon ~]# echo "10.3 != 10.1" | bc
    1
    [root@egon ~]# echo "10.3 != 10.3" | bc
    0
    
    # 应用
    [root@egon ~]# x=10.3
    [root@egon ~]# y=10.1
    [root@egon ~]# [ `echo "$x >= $y" | bc` -eq 1 ] && echo "$x 大于 $y"
    10.3 大于 10.1
    

    总结

    条件测试:

    格式1: test 条件表达式
    格式2: [ 条件表达式 ]
    格式3: (()) 数值比较,运算  C语言
    
    格式4: [[ 条件表达式 ]],支持正则  =~
    

    结合$符号

    $[]    # 整数运算
    $(())  # 整数运算
    
    $()    # 命令替换
    

    其他

    ()     # 子shell中执行
    

    其他元字符

    - 1、`` 与$():取命令的结果
      [root@localhost ~]# echo `pwd`
      /root
      [root@localhost ~]# echo $(pwd)
      /root
    
      不一样的地方在于$()可以嵌套,而``不能嵌套
      [root@localhost ~]# echo $(ls $(pwd))
      
      # 练习
      [root@aliyun test]# touch $(date +%F)_bak.tar.gz
      [root@aliyun test]# ls
      2020-08-24_bak.tar.gz
     
    - 2、~家目录
    
    - 3、.与..
    
    - 4、!调用历史命令、取反
      # 1、调用历史命令
      [root@egon ~]# !1066
      [root@egon ~]# !ls # 匹配最近的一次历史命令
    
      # 2、取反1:对命令的结果取反
      [root@egon ~]# ! pwd
      /root
      [root@egon ~]# echo $?
      1
    
      # 3、取反2:效果与^雷同
      [root@localhost ~]# touch /test/{1.txt,2.txt,a.txt,aaa_bbb.txt}
      [root@localhost ~]# find /test ! -name 1.txt
      /test
      /test/2.txt
      /test/a.txt
      /test/aaa_bbb.txt
      
      [root@localhost ~]# ls /test/[!0-9].txt # .txt前只有一个字符,但是非数字
      /test/a.txt
      [root@localhost ~]# ls /test/[^0-9].txt # .txt前只有一个字符,但是非数字
      /test/a.txt
    
      [root@aliyun test]# ls -a /etc/skel/.[!.]*
    
    - 5、@无特殊意义
    
    - 6、#注释
    
    - 4、$取变量值
      [root@localhost ~]# x=1
      [root@localhost ~]# echo $x
      1
    
    - 5、%、-、+运算符,注意%可以与jobs配合“kill %工作号”杀后台进程。-减号还有区间及cd -回到上一级的意思
      # 数学运算
      # 1、bc是比较常用的linux计算工具了,而且支持浮点运算:
      [root@localhost ~]# res=`echo 1+1 | bc`
      [root@localhost ~]# echo $res
      2
    
      [root@localhost ~]# res=`echo 10 % 3 | bc`
      [root@localhost ~]# echo $res
      1
    
      [root@localhost ~]# res=`echo 1.2+1.3|bc`
      [root@localhost ~]# echo $res
      2.5
    
      [root@localhost ~]# res=`echo 5.0+3.0|bc`
      [root@localhost ~]# echo $res
      8.0
    
      [root@localhost ~]# res=`echo "scale=2;5.0/3.0"|bc`
      [root@localhost ~]# echo $res
      1.66
    
      [root@localhost ~]# res=`echo "scale=2;5.0/6.0"|bc`
      [root@localhost ~]# echo $res
      .83
    
      # 2、expr不支持浮点数计算。而且要注意数字与运算符中的空格
      [root@localhost ~]# res=`expr 5 / 3` # 不支持浮点计算
      [root@localhost ~]# echo $res
      1
    
      [root@localhost ~]# res=`expr 1+1` # 注意:要有空格
      [root@localhost ~]# echo $res
      1+1
      [root@localhost ~]# res=`expr 1 + 1`
      [root@localhost ~]# echo $res
      2
    
      [root@localhost ~]# res=`expr 5 * 3` # 在expr中*号要转义才能用,否则报语法错误
      [root@egon ~]# echo $res
      15
    
      # 3、$(()) 同expr,不支持浮点数运算
      [root@localhost ~]# echo $((1+1))
      2
      [root@localhost ~]# echo $((1.0+2.0))
      -bash: 1.0+2.0: 语法错误: 无效的算术运算符 (错误符号是 ".0+2.0")
    
      # 4、$[]同expr以及$(()),不支持浮点运算
      [root@localhost ~]# x=1
      [root@localhost ~]# echo $[$x+1]
      2
    
      # 5、let 不支持浮点数运算,而且不支持直接输出,只能赋值
      [root@localhost ~]# let res=1+1
      [root@localhost ~]# echo $res
      2
      [root@localhost ~]#
      [root@localhost ~]# let res=50/5
      [root@localhost ~]# echo $res
      10
      [root@localhost ~]# let c=1.3*3
      -bash: let: c=1.3*3: 语法错误: 无效的算术运算符 (错误符号是 ".3*3"
    
      [root@aliyun test]# x=1
      [root@aliyun test]# let x+=10
      [root@aliyun test]# echo $x
      11
    
    - 6、^同!一样
    
    - 7、&后台运行
      [root@localhost home]# echo "hello";sleep 3;echo "world" &
    
    - 8、*任意多个字符
      [root@localhost ~]# touch 1.txt 2.txt aa.txt aaa.txt
      [root@localhost ~]# rm -rf *.txt
      [root@localhost ~]# touch 1.txt 2.txt aa.txt aaa.txt a1c.txt
      [root@localhost ~]# ls *.txt
      1.txt 2.txt a1c.txt aaa.txt aa.txt
    
    - 9、()在子shell中执行
      [root@localhost ~]# (x=1)
      [root@localhost ~]# echo $x
    
      应用
      [root@localhost ~]# (umask 066;touch a.txt) # umask的设置只在子shell中有效
      [root@localhost ~]# ll a.txt
      -rw-------. 1 root root 0 8月 13 15:22 a.txt
      [root@localhost ~]# touch b.txt
      [root@localhost ~]# ll b.txt
      -rw-r--r--. 1 root root 0 8月 13 15:23 b.txt
    
    - 10、_下划线:无特殊意义,可以用于名字的声明
      [root@localhost ~]# tar -czvf `date +%F_%H:%M:%S`_bak.tar.gz /etc/
    
    - 11、=赋值,==判断相等性
      [root@localhost ~]# [ 1 == 1 ] # 条件1 == 1的左右两边必须有空格
      [root@localhost ~]# echo $? # 判断上一条命令的结果是否为真,0=》true
      0
    
    - 12、|管道:把一个进程的处理结果传递给另外一个进程
      [root@localhost ~]# ps aux | grep python
    
    
      |管道命令的作用,是将左侧命令的标准输出转换为标准输入,提供给右侧命令作为参数。但是,大多数命令都不接受标准输入作为参数,只能直接在命令行输入参数,这导致无法用管道命令传递参数。比如echo命令就不接受管道传参。
      $ echo "hello world" | echo
      xargs命令的作用,是将标准输入转为命令行参数,例如
      $ echo "hello world" | xargs echo
      hello world
    
      [root@localhost ~]# find /home/ -type d -name "test*" |xargs ls
      1.txt 2.txt 3.txt
      [root@localhost ~]# ls /home/test
      1.txt 2.txt 3.txt
    
    - 13、转义特殊字符
      [root@localhost ~]# mkdir a b.txt # 虽然可以,但不推荐
      [root@localhost ~]# ll
      总用量 0
      drwxr-xr-x. 2 root root 6 8月 13 15:35 a b.txt
    
      
      [root@localhost ~]# echo $RMB # 默认会当成变量
    
      [root@localhost ~]# echo '$RMB' # 取消特殊意义
      $RMB
      [root@localhost ~]# echo $RMB # 取消特殊意义
      $RMB
    
    - 14、[]条件测试,后续会详细介绍
      [root@localhost ~]# name="egon"
      [root@localhost ~]# [ $name == "egon" ];echo $?
      0
      [root@localhost ~]# name="adf"
      [root@localhost ~]# [ $name == "egon" ];echo $?
      1
    
      [root@localhost ~]# [ -d /test ];echo $?
      0
      [root@localhost ~]#
    
    - 15、引号
      '' 强引用(在单引号中都视为普通字符)
      " " 弱引用 (在双引号中保留变量)
    
      [root@localhost ~]# x=111
      [root@localhost ~]# echo "$x"
      111
      [root@localhost ~]# echo '$x'
      $x
      [roo
    
    - 16、;与&&与||连接多条命令
      [root@localhost home]# gagaga;ls # 不论前一条命令运行成功与否,都会执行后续命令
      bash: gagaga: 未找到命令...
      egon
      [root@localhost home]# gagaga && ls # 只有前一条命令执行成功,才会执行后续命令
      bash: gagaga: 未找到命令...
    
      [root@localhost home]# ls /test || mkdir /test # 前一条命令执行不成功才会执行后续命令
      0.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
    
    - 17、:空命令,真值
      [root@egon ~]# :
      [root@egon ~]# echo $?
      0
    
    - 18、/路径分隔符
    
    - 19、{}循环列表
      [root@localhost home]# touch /test/{0..9}.txt
      [root@localhost home]# ls /test/
      0.txt 1.txt 2.txt 3.txt 4.txt 5.txt 6.txt 7.txt 8.txt 9.txt
      [root@localhost ~]# touch {1..3}{a..d}.txt
      [root@localhost ~]# ls
      1a.txt 1b.txt 1c.txt 1d.txt 2a.txt 2b.txt 2c.txt 2d.txt 3a.txt 3b.txt 3c.txt 3d.txt
    
      [root@egon ~]# x=100
      [root@egon ~]# echo ${x}% # 控制变量名的范围
      100%
      [root@egon ~]#
      [root@egon ~]# echo $xrmb
    
      [root@egon ~]# echo ${x}rmb
      100rmb
    
    - 20、重定向
      > >> 输出重定向
      < << 输入重定向
      > 覆盖 >> 追加
      [root@localhost home]# cat >> a.txt << EOF
      > 111
      > 222
      > 333
      > EOF
      
      0标准输入、1标准正确输出、2标准错误输出,&标准正确和错误输出
      [root@localhost home]# pwd 1>a.txt
      [root@localhost home]# cat a.txt
      /home
      [root@localhost home]# gagag 2>a.txt
      [root@localhost home]# cat a.txt
      bash: gagag: 未找到命令...
      [root@localhost home]# gagaga &>/dev/null
      
      < << 输入重定向
      [root@localhost ~]# mysql -uroot -p123 < bbs.sql
      [root@localhost home]# grep root < /etc/passwd
      root:x:0:0:root:/root:/bin/bash
      operator:x:11:0:operator:/root:/sbin/nologin
      
    
      [root@localhost home]# dd if=/dev/zero of=/a.txt bs=1M count=10
      记录了10+0 的读入
      记录了10+0 的写出
      10485760字节(10 MB)已复制,0.024387 秒,430 MB/秒
      [root@localhost home]# dd </dev/zero >/b.txt bs=1M count=10
      记录了10+0 的读入
      记录了10+0 的写出
      10485760字节(10 MB)已复制,0.0202365 秒,518 MB/秒
     
      [root@localhost home]# ll /a.txt
      -rw-r--r--. 1 root root 10485760 8月 13 16:02 /a.txt
      [root@localhost home]# ll /b.txt
      -rw-r--r--. 1 root root 10485760 8月 13 16:03 /b.txt
    
    - 21、?任意一个字符
      [root@localhost ~]# ls ??.txt
      aa.txt
      [root@localhost ~]# ls a?c.txt
      a1c.txt
      [root@localhost ~]# rm -rf *.txt
    
    - 22、范围中的任意一个字符 [12] [ac] [a-z] [0-9]
      [root@localhost ~]# touch a1c a2c axc aXc axd
      [root@localhost ~]# ls a?c
      a1c a2c axc aXc
      [root@localhost ~]# ls a[1x]c
      a1c axc
      [root@localhost ~]# ls a[a-z]c
      axc aXc
      [root@localhost ~]# ls a[A-Z]c # 不区分大小写
      axc aXc
      [root@localhost ~]# ls a[x]c
      axc
      [root@localhost ~]# ls a[X]c
      aXc
      [root@localhost ~]# ls a[0-9]c
      a1c a2c
      [root@localhost ~]# ls /dev/sd[a-z]*
      /dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb1
    
  • 相关阅读:
    20181223何家豪 Exp3-免杀原理
    实验一 密码引擎-3-电子钥匙功能测试 20181223何家豪
    Exp2-后门原理与实践 20181223何家豪
    实验四 Web服务器-socket编程
    Faster Rcnn训练自己的数据集过程大白话记录
    python线性数据结构
    越来越清晰的TFRecord处理图片的步骤
    更加清晰的TFRecord格式数据生成及读取
    生成TFRecord文件完整代码实例
    python 多进程处理图像,充分利用CPU
  • 原文地址:https://www.cnblogs.com/zhaokunhao/p/14889808.html
Copyright © 2011-2022 走看看