• 十 字符串处理


    变量子串常用操作:

    表达式含义
    ${#string} $string的长度
       
    ${string:position} 在$string中, 从位置$position开始提取子串
    ${string:position:length} 在$string中, 从位置$position开始提取长度为$length的子串
       
    ${string#substring} 从变量$string的开头, 删除最短匹配$substring的子串
    ${string##substring} 从变量$string的开头, 删除最长匹配$substring的子串
    ${string%substring} 从变量$string的结尾, 删除最短匹配$substring的子串
    ${string%%substring} 从变量$string的结尾, 删除最长匹配$substring的子串
       
    ${string/substring/replacement} 使用$replacement, 来代替第一个匹配的$substring
    ${string//substring/replacement} 使用$replacement, 代替所有匹配的$substring
    ${string/#substring/replacement} 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
    ${string/%substring/replacement} 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring

    说明:

    $substring可以是一个正则表达式.

    返回长度

    ${#string} :返回$string的长度

    字符串截取

    字符串截取            格式                                           
    使用${}表达式         ${var:起始位置:长度};编号从0开始,可省略                
    使用expr substr      expr substr "$var" 起始位置 长度;起始位置编号从1开始
    使用cut工具        echo $var | cut -b 起始位置-结束位置;起始位置编号从1开始

    说明:

    ${string:position}           在$string中, 从位置$position开始提取子串
    ${string:position:length}    在$string中, 从位置$position开始提取长度为$length的子串

    字符串的匹配删除

         格式                         
    ${变量名#*关键词}      从左到右,最短匹配删除;#用来删除头部,*通配 
    ${变量名##*关键词}     从左到右,最长匹配删除;#用来删除头部,*通配    
    
    ${变量名%关键词*}      从右到左,最短匹配删除;%用来删除尾部,*通配    
    ${变量名%%关键词*}     从右到左,最长匹配删除;%用来删除尾部,*通配   

    解析:

    ${string#substring}    从变量$string的开头, 删除最短匹配$substring的子串
    ${string##substring}    从变量$string的开头, 删除最长匹配$substring的子串
    ${string%substring}    从变量$string的结尾, 删除最短匹配$substring的子串
    ${string%%substring}    从变量$string的结尾, 删除最长匹配$substring的子串

    文件批量改名

    例子:将扩展名.doc改为.txt

    
    #!/bin/bash
    for FILE in *.doc
    do
      mv $FILE ${FILE%.doc}.txt
    done

    字符串的替换

        格式
    ${var/old/new}           只替换第一个匹配结果   
    ${var//old/new}          替换全部匹配结果    
    ${string/#substring/replace}   如果$string前缀匹配$substring,就用$replace来代替匹配$substring
    ${string/%substring/replace}   如果$string后缀匹配$substring,就用$replace来代替匹配$substring

    解析:

    ${string/substring/replacement}     使用$replacement, 来代替第一个匹配的$substring
    ${string//substring/replacement}     使用$replacement, 代替所有匹配的$substring
    ${string/#substring/replacement}     如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
    ${string/%substring/replacement}     如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring

     依次举例说明:

    
    定义OLDBOY变量,内容为”I am oldboy”
    
    
    I am oldboy
    
    1)返回字符串OLDBOY变量字符串的长度
    
    [root@Web ~]# echo ${#OLDBOY}
    
    11
    
    [root@Web ~]# echo ${OLDBOY} |wc -m
    
    12
    
    2)截取OLDBOY变量字符串从第2个字符之后开始取,默认取后面字符的全部,第2个字符不包括在内。也可理解为删除前面的多少个字符
    
    [root@Web ~]# echo ${OLDBOY:2}
    
    am oldboy
    
     
    
    3)截取OLDBOY变量字符串从第2个字符之后开始取,取两个字符。
    
    [root@Web ~]# echo ${OLDBOY:2:2}
    
    am
    
    提示:类似cut -c参数
    
    [root@Web ~]# echo ${OLDBOY}|cut -c 1-4
    
    I am
    
    [root@Web ~]# echo ${OLDBOY}|cut -c 3-4
    
    am
    
    4)从变量$OLDBOY开头开始删除最短匹配”I am”子串
    
    [root@Web ~]# echo ${OLDBOY#I am}
    
    oldboy
    
     
    
    5)从变量$OLDBOY开头开始删除最长匹配”I am old”子串
    
    [root@Web ~]# echo ${OLDBOY##I am old}
    
    boy
    
    6)从变量$OLDBOY结尾开始删除最短匹配oldboy子串
    
    [root@Web ~]# echo ${OLDBOY%oldboy}
    
    I am
    
    7)从变量$OLDBOY结尾开始删除最长匹配boy子串
    
    [root@Web ~]# echo ${OLDBOY%%boy}
    
    I am old
    
    8)使用etiantian字符串,来代替变量$OLDBOY第一个匹配的oldboy字符串
    
    [root@Web ~]# echo ${OLDBOY/oldboy/etiantian}
    
    I am etiantian
    
     
    
    9)使用etiantian字符串,来代替变量$OLDBOY结尾匹配的oldboy字符串
    
    [root@Web ~]# echo ${OLDBOY/%oldboy/etiantian}
    
    I am etiantian
    
    10)使用He is字符串,来代替从变量$OLDBOY开头开始匹配的I am字符串
    
    [root@Web ~]# echo ${OLDBOY/#I am/He is}
    
    He is oldboy

    生产场景用法实例:

    1)变量结尾删除生产实践:

    功能描述如下表:

     

    ${string#substring}     从变量$string的开头, 删除最短匹配$substring的子串

     批量文件改名案例实践:

    问题1:把下面所有的文件名中的finishied内容去掉。
    [root@localhost ~]# mkdir /test
    [root@localhost ~]# cd /test
    [root@localhost test]# cat a.log 
    stu_102999_2_finish.jpg
    stu_102999_3_finish.jpg
    stu_102999_4_finish.jpg
    [root@localhost test]# for f in `cat a.log`;do touch $f;done
    [root@localhost test]# ll
    总用量 4
    -rw-r--r--. 1 root root 72 3月  30 22:24 a.log
    -rw-r--r--. 1 root root  0 3月  30 22:25 stu_102999_2_finish.jpg
    -rw-r--r--. 1 root root  0 3月  30 22:25 stu_102999_3_finish.jpg
    -rw-r--r--. 1 root root  0 3月  30 22:25 stu_102999_4_finish.jpg
    
    
    [root@localhost test]# cat p.sh 
    for f in `ls *.jpg` 
    do 
        mv $f `echo ${f%finish*}.jpg`
    done
    
    [root@localhost test]# ll
    总用量 8
    -rw-r--r--. 1 root root 72 3月  30 22:24 a.log
    -rw-r--r--. 1 root root  0 3月  30 22:24 cat
    -rw-r--r--. 1 root root 64 3月  30 22:49 p.sh
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_2_.jpg
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_3_.jpg
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_4_.jpg

    2)变量结尾替换生产实践:

    ${string/substring/replacement}     使用$replacement, 来代替第一个匹配的$substring
    问题:把下面文件的大写扩展名变小写扩展名
    
    [root@localhost test]# cat p.sh
    for f in `ls *.jpg` 
    do 
        mv $f `echo "${f/%jpg/JPG}"`
    done
    [root@localhost test]# sh p.sh
    [root@localhost test]# ll
    总用量 8
    -rw-r--r--. 1 root root 72 3月  30 22:24 a.log
    -rw-r--r--. 1 root root  0 3月  30 22:24 cat
    -rw-r--r--. 1 root root 63 3月  30 22:52 p.sh
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_2_.JPG
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_3_.JPG
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_4_.JPG
    
    

     1 命令名称:rename-Rename files

    2 命令功能:给文件重命名

    3命令语法: rename from to file 提示:这里的用法”from to file”一开始会被大家误解,实际上还是看下面表格吧:

    还是看实际例子吧!

    准备测试数据:

    [root@Web ~]# mkdir /test
    [root@Web ~]# cd /test
    [root@Web test]# for f in `seq 9`;do touch foo$f.htm;done
    [root@Web test]# ls -l
    总用量 0
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo1.htm
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo2.htm
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo3.htm
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo4.htm
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo5.htm
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo6.htm
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo7.htm
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo8.htm
    -rw-r--r--. 1 root root 0 4月  12 21:58 foo9.htm
    
    [root@localhost test]# rename .JPG .htm *.JPG
    [root@localhost test]# ll
    总用量 8
    -rw-r--r--. 1 root root 72 3月  30 22:24 a.log
    -rw-r--r--. 1 root root  0 3月  30 22:24 cat
    -rw-r--r--. 1 root root 63 3月  30 22:52 p.sh
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_2_.htm
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_3_.htm
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_102999_4_.htm
    
    
    [root@localhost test]# rename 102999 oldboy *.htm
    [root@localhost test]# ll
    总用量 8
    -rw-r--r--. 1 root root 72 3月  30 22:24 a.log
    -rw-r--r--. 1 root root  0 3月  30 22:24 cat
    -rw-r--r--. 1 root root 63 3月  30 22:52 p.sh
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_oldboy_2_.htm
    -rw-r--r--. 1 root root  0 3月  30 22:48 stu_oldboy_3_.htm

     

    更多批量改名案例,请看老男孩的博文《Linux下批量修改文件名精彩解答案例分享》

    https://blog.51cto.com/oldboy/711342

    变量初值处理

    取值

    取值,${var:-word}

    
    若变量var已存在且非null,则返回$var的值
    否则返回字串"word",变量var值不变
    用途: 如果变量没定义 返回默认值

    赋值

    赋值,${var:=word}

    若变量var已存在且非null,则返回$var的值
    否则返回字串"word",并赋值给变量var
    用途: 如果变量没定义 给变量赋值

    有值时提示

    有值时提示,${var:+"提示信息"}

    若变量var已存在且非null,则给出提示
    否则返回NUll(空值)
    用途 : 测试变量是否定义

    无值时提示

    无值时提示,${var:?"提示信息"}

    若变量var已存在且非null,则返回$var的值
    否则给出提示信息(若省略,则用默认提示)
    用途: 捕捉由于变量未定义所导致的错误

    练习:

    a、提示输入一个正整数x,求从1x的和

    b、若用户未输入值(直接回车),则赋值x=1

    #!/bin/bash
    read -p "请输入一个正整数:" x
    x=${x:-1};i=1;SUM=0
    while [ $i -le $x ]
    do
      let SUM+=i;let i++
    done
    echo "从1到$x的总和是:$SUM"

    例题:

    mycluster.sh

    检查集群中主机的物理连接状态,要求如下

    能够设置检查主机的台数 和 检查哪些主机

    把不在线主机的ip地址和时间保存到/clusterdir目录下的stat.txt文件里并把不在线主机的ip地址 时间 台数 输出到屏幕上

    下面一次举例说明:

    1${value:-word}  

    当变量未定义或者值为空时,返回值为word内容,否则返回变量的值

    举例:

    [zgy@Web ~]$ result=${test:-UNSET}

    [zgy@Web ~]$ echo $result

    UNSET

    [zgy@Web ~]$ echo $test

                ==>这里是空

    结论:当test变量没内容时,就返回了后面的UNSET.

    [zgy@Web ~]$ test='oldboy'

    [zgy@Web ~]$ result=${test:-UNSET}

    [zgy@Web ~]$ echo $result

    Oldboy

    提示:这个变量可以用来判断变量是否没有定义

    (2)${value:=word}  

    [zgy@Web ~]$ unset result

    [zgy@Web ~]$ echo $result

    [zgy@Web ~]$ unset test

    [zgy@Web ~]$ echo $test

    [zgy@Web ~]$ result=${test:=UNSET}

    [zgy@Web ~]$ echo $result

    UNSET

    [zgy@Web ~]$ echo $test

    UNSET

    [zgy@Web ~]$ test=oldboy

    [zgy@Web ~]$ result=${test:=UNSET}

    [zgy@Web ~]$ echo $result

    oldboy

    [zgy@Web ~]$ echo $test

    Oldboy

    提示:这个变量功能可以解决变量没有定义的问题,确保变量始终有值

    (3)${value:?”word”}  

    [zgy@Web ~]$ echo ${value:?"not defined"}

    -bash: value: not defined

    [zgy@Web ~]$ value=1

    [zgy@Web ~]$ echo ${value:?"not defined"}

    1

    [zgy@Web ~]$ unset value

    [zgy@Web ~]$ echo ${value:?"not defined"}

    -bash: value: not defined

    提示:用于捕捉由于未定义而导致的错误,如:"not defined"

    (4)${var:+word}  

    [zgy@Web ~]$ r=${value:+1}

    [zgy@Web ~]$ echo $r

    [zgy@Web ~]$ value=oldboy

    [zgy@Web ~]$ echo $r

    [zgy@Web ~]$ r=${value:+1}

    [zgy@Web ~]$ echo $r

    1

    提示:此功能可用于测试变量是否存在。

    (5){value:-word}去掉冒号

    [zgy@Web ~]$ httpd=${HTTPD-/usr/sbin/httpd}
    
    [zgy@Web ~]$ pidfile=${PIDFILE-/var/run/httpd,pid}
    
    [zgy@Web ~]$ echo $httpd $pidfile
    
    /usr/sbin/httpd /var/run/httpd,pid
    
    [zgy@Web ~]$ echo $HTTPD $PIDFILE

    结论:变量没定义就用-号后面的替代

    (6)应用例子:/etc/init.d/httpd(注意红色部分)

    apachectl=/usr/sbin/apachectl
    
    httpd=${HTTPD-/usr/sbin/httpd}
    
    prog=httpd
    
    pidfile=${PIDFILE-/var/run/httpd/httpd.pid}
    
    lockfile=${LOCKFILE-/var/lock/subsys/httpd}
    
    RETVAL=0

    提示:用yum安装的httpd

    系统服务crond脚本使用案例:/etc/init.d/crond

    如图:

    (2)${value:=word}

    与前者类似,只是若变量未定义或者值为空时,在返回word的值的同时将word赋值给value

    [root@Web ~]# OLD=${value:=word}
    
    [root@Web ~]# echo $OLD
    
    word
    
    [root@Web ~]# echo $value
    
    word
    
    [root@Web ~]# value="test"
    
    [root@Web ~]# OLD=${value:=word}
    
    [root@Web ~]# echo $OLD
    
    test
    
    [root@Web ~]# echo $value
    
    test

    注:变量替换的值也可以是``括起来的命令:$USERDIR={$Mydir:-`pwd`}

    (3)${value:?message}

     若变量以赋值的话,正常替换。否则将消息message送到标准错误输出(若此替换出现在shell程序中,那么该程序将中止运行)

    生产应用场景:

    1)/etc/init.d/httpd

    2)/etc/init.d/crond

    3)对变量的路径进行操作,最好先判断路径是否为空。特别是删除操作,容易有危险。

    [root@Web ~]#sed -i ‘1d’d.sh
    
    [root@Web ~]# cat d.sh
    
    path=/server/backup
    
    find ${path:=/tmp/} -name “*.tar.gz” -type f | xargs rm -f
    
    [root@Web ~]#sh -x d.sh

    变量的处理计算变量长度与其他不同方法的耗时对比:

    [root@Web ~]# chars=`seq -s " " 100`
    
    [root@Web ~]# echo $chars
    
    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
    
    [root@Web ~]# echo ${#chars}
    
    291
    
    [root@Web ~]# echo $chars|wc -m
    
    292
    
    [root@Web ~]# echo $(expr length "$chars")
    
    291
    
    [root@Web ~]# time for i in $(seq 11111);do count=${#chars};done;
    
     
    
    real 0m0.671s
    
    user 0m0.950s
    
    sys 0m0.002s
    
    [root@Web ~]# time for i in $(seq 11111);do count=`echo ${chars}|wc -m`;done;
    
     
    
    real 0m27.419s
    
    user 0m1.021s
    
    sys 0m4.189s
    
    [root@Web ~]# time for i in $(seq 11111);do count=`echo expr length "${chars}"`;done;
    
     
    
    real 0m6.513s
    
    user 0m0.346s
    
    sys 0m1.376s

      我们看到速度相差几十到上百倍,一般情况调用外部命令处理,与内置功能操作性能相差较大。在shell编程中,我们应尽量用内置操作或函数完成。

    变量处理替换的一些参考资料

    man bash变量处理大全<==学习要尽量去找一手资料
    
    http://www.cnblogs.com/chengmo/archive/2010/10/02/1841355.html
  • 相关阅读:
    PriorityQueue详解
    Queue介绍
    Dubbo面试踩坑
    Java中Integer和ThreadLocal
    Java中Deque特性及API
    由ubuntu装好想到的
    双系统试水上岸
    终于意识到BIM确实火了
    读阿里机器学习平台的一些总结
    继续ubuntu和遇到的easybcd的坑
  • 原文地址:https://www.cnblogs.com/zhongguiyao/p/8984881.html
Copyright © 2020-2023  润新知