简介

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

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

字符串切片

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

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

基于pattern取子串

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

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

查找替换

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

  1. [root@c7-server ~]# echo ${userinfo}
  2. root:x:::root:/root:/bin/bash
  3. [root@c7-server ~]# echo ${userinfo/r??t/centos}
  4. centos:x:::root:/root:/bin/bash

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

  1. [root@c7-server ~]# echo ${userinfo}
  2. root:x:::root:/root:/bin/bash
  3. [root@c7-server ~]# echo ${userinfo//r??t/centos}
  4. centos:x:::centos:/centos:/bin/bash

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

  1. [root@c7-server ~]# echo ${userinfo}
  2. root:x:::root:/root:/bin/bash
  3. [root@c7-server ~]# echo ${userinfo/#r??t/centos}
  4. centos:x:::root:/root:/bin/bash

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

  1. [root@c7-server ~]# echo ${userinfo}
  2. root:x:::root:/root:/bin/bash
  3. [root@c7-server ~]# echo ${userinfo/%bash/zsh}
  4. root:x:::root:/root:/bin/zsh

查找删除

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

  1. [root@c7-server ~]# echo ${userinfo}
  2. root:x:::root:/root:/bin/bash
  3. [root@c7-server ~]# echo ${userinfo/root}
  4. :x:::root:/root:/bin/bash

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

  1. [root@c7-server ~]# echo ${userinfo}
  2. root:x:::root:/root:/bin/bash
  3. [root@c7-server ~]# echo ${userinfo//root}
  4. :x::::/:/bin/bash

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

  1. [root@c7-server ~]# echo ${userinfo}
  2. root:x:::root:/root:/bin/bash
  3. [root@c7-server ~]# echo ${userinfo/#root}
  4. :x:::root:/root:/bin/bash

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

  1. [root@c7-server ~]# echo ${userinfo}
  2. root:x:::root:/root:/bin/bash
  3. [root@c7-server ~]# echo ${userinfo/%bash}
  4. root:x:::root:/root:/bin/

字符大小写转换

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

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

  1. [root@c7-server ~]# name=RenDanChaoXian
  2. [root@c7-server ~]# echo ${name^^}
  3. RENDANCHAOXIAN
  4. [root@c7-server ~]# echo ${name,,}
  5. rendanchaoxian

变量赋值

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

  1. [root@c7-server ~]# echo ${name}
  2. RenDanChaoXian
  3. [root@c7-server ~]# echo ${name:-alongdidi}
  4. RenDanChaoXian
  5. [root@c7-server ~]# unset name
  6. [root@c7-server ~]# echo ${name:-alongdidi}
  7. alongdidi
  8. [root@c7-server ~]# echo ${name}
  9.  
  10. [root@c7-server ~]# name=
  11. [root@c7-server ~]# echo ${name:-alongdidi}
  12. alongdidi
  13. [root@c7-server ~]# echo ${name}
  14.  
  15. [root@c7-server ~]#

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

  1. [root@c7-server ~]# name=zwl
  2. [root@c7-server ~]# echo ${name}
  3. zwl
  4. [root@c7-server ~]# echo ${name:=alongdidi}
  5. zwl
  6. [root@c7-server ~]# unset name
  7. [root@c7-server ~]# echo ${name:=alongdidi}
  8. alongdidi
  9. [root@c7-server ~]# echo ${name}
  10. alongdidi
  11. [root@c7-server ~]# name=
  12. [root@c7-server ~]# echo ${name:=alongdidi}
  13. alongdidi
  14. [root@c7-server ~]# echo ${name}
  15. alongdidi

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

  1. [root@c7-server ~]# name=
  2. [root@c7-server ~]# echo ${name:+alongdidi}
  3.  
  4. [root@c7-server ~]# unset name
  5. [root@c7-server ~]# echo ${name:+alongdidi}
  6.  
  7. [root@c7-server ~]# name=zwl
  8. [root@c7-server ~]# echo ${name:+alongdidi}
  9. alongdidi
  10. [root@c7-server ~]# echo ${name}
  11. zwl
  12. [root@c7-server ~]#

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

  1. [root@c7-server ~]# name=
  2. [root@c7-server ~]# echo ${name:?"There is something wrong"}
  3. -bash: name: There is something wrong
  4. [root@c7-server ~]# unset name
  5. [root@c7-server ~]# echo ${name:?"There is something wrong"}
  6. -bash: name: There is something wrong
  7. [root@c7-server ~]# name=zwl
  8. [root@c7-server ~]# echo ${name:?"There is something wrong"}
  9. 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?

Bash脚本编程之字符串处理的更多相关文章

  1. 6-3 bash脚本编程之五 字符串测试及for循环

    1. 字符测试 ==:等号两边要有空格,否则会被认为是赋值. !=:  测试是否相等,记住如果不等为真,等为假. -n string: 测试指定字符串是否为空,空位真,不空为假. -s string: ...

  2. 高级Bash脚本编程指南(27):文本处理命令(三)

    高级Bash脚本编程指南(27):文本处理命令(三) 成于坚持,败于止步 处理文本和文本文件的命令 tr 字符转换过滤器. 必须使用引用或中括号, 这样做才是合理的. 引用可以阻止shell重新解释出 ...

  3. 高级bash脚本编程(三)

    高级bash脚本编程 知识点 compound 和 comparison -a 逻辑与 exp1 -a exp2 如果表达式 exp1 和 exp2 都为真的话,那么结果为真. -o 逻辑或 exp1 ...

  4. 高级Bash脚本编程(二)

    高级Bash脚本编程(二) 退出 退出状态码 退出:exit 被用来结束一个脚本,它也返回一个值,并且这个值会传递给脚本的父进程,父进程会使用这个值做下一步的处理. 每个命令都会返回一个退出状态码,成 ...

  5. Bash脚本编程总结

    bash脚本编程之用户交互: read [option]… [name …]  -p ‘PROMPT’  -t TIMEOUT bash -n /path/to/some_script  检测脚本中的 ...

  6. bash脚本编程知识储备

    bash脚本编程:     脚本程序:解释器解释执行: 首先得理清一些琐碎的知识点,我尽量把我所学的帮朋友一起梳理一下 编程环境:(我会在接下来的篇章,图文例子三结合的方式带大家一起学习)       ...

  7. Bash脚本编程之算术运算

    简介 Bash所支持的算术运算和C语言是一样的,这里指的是操作符(operator)以及它们的优先级(precedence).结合性(associativity)和值,详见Shell Arithmet ...

  8. Bash脚本编程之数组

    数组简介 在bash脚本编程当中,变量是存储单个元素的内存空间:而数组是存储多个元素的一段连续的内存空间. 数组由数组名和下标构成,如下. ARRAY_NAME[SUBSCRIPT] 数组按照下标的类 ...

  9. Bash脚本编程学习笔记06:条件结构体

    简介 在bash脚本编程中,条件结构体使用if语句和case语句两种句式. if语句 单分支if语句 if TEST; then CMD fi TEST:条件判断,多数情况下可使用test命令来实现, ...

随机推荐

  1. day20190915write from memory

    jQuery_Chapter02_20190912/ jQuery操作类样式.html <!DOCTYPE html> <html> <head> <meta ...

  2. 【Android - 自定义View】之View的measure过程解析

    measure(测量)过程是View的工作流程中最开始.最核心的过程,在这个过程中负责确定View的测量宽/高. 对于View和ViewGroup,measure过程有不同的执行方法:如果目标是一个原 ...

  3. for源码实现

    for源码实现 我们知道,java的while和for基本上是实现一样的功能,这样会不会有一点缺点,同时java的迭代器显得尤为的麻烦. python的for和while就不同了,在实现迭代的功能的情 ...

  4. C语言I博客作业01

    C语言I博客作业01 作业1 这个作业属于哪个课程? C语言程序设计I 这个作业要求在哪里? https://edu.cnblogs.com/campus/zswxy/CST2019-2/homewo ...

  5. apache虚拟主机配置的3种方式

    Apache的虚拟主机功能 (Virtual Host) 是可以让一台服务器基于IP.主机名或端口号实现提供多个网站服务的技术. 下面我介绍一下这3种方式具体的配置流程: 一.基于ip地址 首先我们需 ...

  6. 2019-2020-1 20199304《Linux内核原理与分析》第二周作业

    计算机工作原理 存储程序计算机模型 冯·诺依曼体系结构 冯·诺依曼体系结构如图所示: 冯·诺依曼体系结构包含五大部分 运算器:在控制器的统一控制下,负责对数据进行加工.完成各种运算,如算术运算.逻辑运 ...

  7. Kubernetes 时代的安全软件供应链

    点击下载<不一样的 双11 技术:阿里巴巴经济体云原生实践> 本文节选自<不一样的 双11 技术:阿里巴巴经济体云原生实践>一书,点击上方图片即可下载! 作者 汤志敏  阿里云 ...

  8. Python如何爬取实时变化的WebSocket数据

    一.前言 作为一名爬虫工程师,在工作中常常会遇到爬取实时数据的需求,比如体育赛事实时数据.股市实时数据或币圈实时变化的数据.如下图: Web 领域中,用于实现数据'实时'更新的手段有轮询和 WebSo ...

  9. where 和having 的区别

    where : 约束声明,在查询结果返回之前对数据库中的查询条件进行约束    其后不能写聚合函数 having  过滤声明,在查询结果返回之后进行过滤,

  10. HTML_body中常用的标签部分

    meta: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <t ...