• Bash脚本编程学习笔记10:参数展开


    简介

    原标题叫做《Bash脚本编程之字符串处理》。

    其实这里说得字符串处理,对应的是bash官网中的【Shell Parameter Expansion】,不过直接去看这部分内容实在是太难以理解了。就按照马哥所说的字符串处理会比较好理解,平常使用应该也是足够的了。

    字符串切片

    这块在上一篇讲解数组的文章中,也大概提到了Shell Parameter Expansion除了可以对数组(array)切片以外,还可以对变量切片。

    ${var:offset:number}
    ${var: length}
    [root@c7-server ~]# name="zhangwenlong"
    [root@c7-server ~]# echo ${name}
    zhangwenlong
    [root@c7-server ~]# echo ${name:2:5}
    angwe
    [root@c7-server ~]# echo ${name: -4}
    long

    基于pattern取子串

    这里的pattern,应该是glob或者类glob的,而非正则表达式,详见官方的Pattern Matching

    ${var#*pattern}:在变量var的值中自左向右查询pattern,若查询到,则删除值首部至第一次出现的pattern之间的所有字符。
    [root@c7-server ~]# echo ${name}
    zhangwenlong
    [root@c7-server ~]# echo ${name#*wen}
    long
    [root@c7-server ~]# echo ${name}
    zhangwenlong
    ${var##*pattern}:在变量var的值中自左向右查询pattern,若查询到,则删除值首部至最后一次出现的pattern之间的所有字符。
    [root@c7-server ~]# echo ${name}
    zhangwenlong
    [root@c7-server ~]# echo ${name#*n}
    gwenlong
    [root@c7-server ~]# echo ${name##*n}
    g
    ${var%pattern*}:在变量var的值中自右向左查询pattern,若查询到,则删除值尾部至第一次出现的pattern之间的所有字符。
    ${var%%pattern*}:在变量var的值中自右向左查询pattern,若查询到,则删除值尾部至最后一次出现的pattern之间的所有字符。
    [root@c7-server ~]# echo ${name}
    zhangwenlong
    [root@c7-server ~]# echo ${name%n*}
    zhangwenlo
    [root@c7-server ~]# echo ${name%%n*}
    zha

    查找替换

    ${var/PAT/SUB}:在变量var的值中从左往右查找,只有第一次出现的PAT(pattern)会被替换成SUB(substitute)。

    [root@c7-server ~]# echo ${userinfo}
    root:x:0:0:root:/root:/bin/bash
    [root@c7-server ~]# echo ${userinfo/r??t/centos}
    centos:x:0:0:root:/root:/bin/bash

    ${var//PAT/SUB}:在变量var的值中从左往右查找,所有出现的PAT都会被替换成SUB。

    [root@c7-server ~]# echo ${userinfo}
    root:x:0:0:root:/root:/bin/bash
    [root@c7-server ~]# echo ${userinfo//r??t/centos}
    centos:x:0:0:centos:/centos:/bin/bash

    ${var/#PAT/SUB}:在变量var的值中从左往右查找,只有行首出现的PAT都会被替换成SUB。

    [root@c7-server ~]# echo ${userinfo}
    root:x:0:0:root:/root:/bin/bash
    [root@c7-server ~]# echo ${userinfo/#r??t/centos}
    centos:x:0:0:root:/root:/bin/bash

    ${var/%PAT/SUB}:在变量var的值中从左往右查找,只有行尾出现的PAT都会被替换成SUB。

    [root@c7-server ~]# echo ${userinfo}
    root:x:0:0:root:/root:/bin/bash
    [root@c7-server ~]# echo ${userinfo/%bash/zsh}
    root:x:0:0:root:/root:/bin/zsh

    查找删除

    ${var/PAT}:在变量var的值中从左往右查找,只有第一次出现的PAT会被删除。

    [root@c7-server ~]# echo ${userinfo}
    root:x:0:0:root:/root:/bin/bash
    [root@c7-server ~]# echo ${userinfo/root}
    :x:0:0:root:/root:/bin/bash

    ${var//PAT}:在变量var的值中从左往右查找,所有出现的PAT会被删除。

    [root@c7-server ~]# echo ${userinfo}
    root:x:0:0:root:/root:/bin/bash
    [root@c7-server ~]# echo ${userinfo//root}
    :x:0:0::/:/bin/bash

    ${var/#PAT}:在变量var的值中从左往右查找,只有行首出现的PAT会被删除。

    [root@c7-server ~]# echo ${userinfo}
    root:x:0:0:root:/root:/bin/bash
    [root@c7-server ~]# echo ${userinfo/#root}
    :x:0:0:root:/root:/bin/bash

    ${var/%PAT}:在变量var的值中从左往右查找,只有行尾出现的PAT会被删除。

    [root@c7-server ~]# echo ${userinfo}
    root:x:0:0:root:/root:/bin/bash
    [root@c7-server ~]# echo ${userinfo/%bash}
    root:x:0:0:root:/root:/bin/

    字符大小写转换

    ${var^^}:将变量var中的所有小写字符转换成大写。

    ${var,,}:将变量var中的所有大写字符转换成小写。

    [root@c7-server ~]# name=RenDanChaoXian
    [root@c7-server ~]# echo ${name^^}
    RENDANCHAOXIAN
    [root@c7-server ~]# echo ${name,,}
    rendanchaoxian

    变量赋值

    ${var:-VALUE}:如果变量var为空或者未设置,则返回VALUE;否则返回变量var的值。注意,变量name本身的值不会被修改。

    [root@c7-server ~]# echo ${name}
    RenDanChaoXian
    [root@c7-server ~]# echo ${name:-alongdidi}
    RenDanChaoXian
    [root@c7-server ~]# unset name
    [root@c7-server ~]# echo ${name:-alongdidi}
    alongdidi
    [root@c7-server ~]# echo ${name}
    
    [root@c7-server ~]# name=
    [root@c7-server ~]# echo ${name:-alongdidi}
    alongdidi
    [root@c7-server ~]# echo ${name}
    
    [root@c7-server ~]#

    ${var:=VALUE}:如果变量var为空或者未设置,则返回VALUE,并将VALUE赋值给变量var;否则返回变量var的值。

    [root@c7-server ~]# name=zwl
    [root@c7-server ~]# echo ${name}
    zwl
    [root@c7-server ~]# echo ${name:=alongdidi}
    zwl
    [root@c7-server ~]# unset name
    [root@c7-server ~]# echo ${name:=alongdidi}
    alongdidi
    [root@c7-server ~]# echo ${name}
    alongdidi
    [root@c7-server ~]# name=
    [root@c7-server ~]# echo ${name:=alongdidi}
    alongdidi
    [root@c7-server ~]# echo ${name}
    alongdidi

    ${var:+VALUE}:如果变量为空或者未设置,那么不会返回任何值。否则则返回VALUE的值。注意,变量name本身的值不会被修改。

    [root@c7-server ~]# name=
    [root@c7-server ~]# echo ${name:+alongdidi}
    
    [root@c7-server ~]# unset name
    [root@c7-server ~]# echo ${name:+alongdidi}
    
    [root@c7-server ~]# name=zwl
    [root@c7-server ~]# echo ${name:+alongdidi}
    alongdidi
    [root@c7-server ~]# echo ${name}
    zwl
    [root@c7-server ~]#

    ${var:?ERROR_INFO}:如果变量var为空或者未设置,则返回错误信息ERROR_INFO;否则返回变量var的值。

    [root@c7-server ~]# name=
    [root@c7-server ~]# echo ${name:?"There is something wrong"}
    -bash: name: There is something wrong
    [root@c7-server ~]# unset name
    [root@c7-server ~]# echo ${name:?"There is something wrong"}
    -bash: name: There is something wrong
    [root@c7-server ~]# name=zwl
    [root@c7-server ~]# echo ${name:?"There is something wrong"}
    zwl

    练习

    写一个脚本,实现如下功能:

      提示用户输入一个可执行的命令的名称,如ls。

      获取该命令所依赖的库文件列表(借助ldd命令)。

      复制命令至某目标目录(例如:/mnt/sysroot/,即将此目录当做新的根目录)下的对应路径中。

        bash, /bin/bash --> /mnt/sysroot/bin/bash

        useradd, /usr/sbin/useradd --> /mnt/sysroot/usr/sbin/useradd

      复制命令所依赖的库文件至对应的目标目录下。

        /lib64/ld-linux-x8664.so.2 --> /mnt/sysroot/lib64/ld-linux-x8664.so.2

      进阶:每次复制完一个命令后不退出,而是等待用户键入新的需要复制的命令,直到用户显示输入“quit”方可退出脚本。

    答:这道题不懂怎么做。需要注意几个点。

    • 命令(二进制程序)的执行需要库文件的支持,因此需要使用ldd命令列出命令所依赖的库文件信息。
    • ldd命令所显示出来的库文件信息,看不太懂。
    • 可能需要使用到切换根的命令?chroot?
  • 相关阅读:
    TCP协议特点和三次握手/四次挥手
    CAP定理、BASE理论
    对自写的Asp.Net分页控件的应用方式(异步无刷新分页)
    Asp.Net分页控件
    SqlHelper
    简易贪吃蛇
    测试一下
    iOS --- DIY文件名批量修改
    iOS常用 --- NSDictionary 与 NSMutableDictionary
    iOS常用---NSArray,NSMutabuleArray
  • 原文地址:https://www.cnblogs.com/alongdidi/p/bash_parameter_expansion.html
Copyright © 2020-2023  润新知