Pure Bash 1

方飞鸣
2023-12-01

该文档是在学习push-bash-bible的过程中将自己的思考和额外学习的技术点记录下来,方便自己后面查找,希望文中的信息对于看到这篇文章的你也能有所帮助

  1. 去除字符串前后空格
    相对于sed、awk、peal或其他工具,以下是实现去除字符串前后空格的另一种方法

例子如下:

trim_string() {
    # Usage: trim_string "   example   string    "
    : "${1#"${1%%[![:space:]]*}"}"
    : "${_%"${_##*[![:space:]]}"}"
    printf '%s\n' "$_"
}

解析如下:
1.1. :是 shell 内嵌的操作符,在这里主要是要让:后面的表达式正常地转换
1.2. ${_}表示上一个命令的所有参数
1.3. [!space]在 shell 脚本代表空格
1.4. #、##、%、%%的主要用法可以参考:shell中#,##,#,##,% *,%% *的含义及用法 替换字符,在这里我多提及一点,当使用#、##、%、%%的时候,shell 是生成一个字符串代表其结果,对源字符串并没有修改

  1. 去除字符串中所有的空白字符
    相对于sed、awk、peal或其他工具,以下是去除字符串所有空格的另一种方法

例子如下:

trim_all() {
    # Usage: trim_all "   example   string    "
    set -f
    set -- $*
    printf '%s\n' "$*"
    set +f
}

解析如下:
这里主要使用了set这个 shell 内嵌函数
2.1. set -f取消使用通配符,但这个我也不是很懂
2.2. set -- $*将所有的输入参数根据IFS进行分割后,再将新结果赋予成位置参数(positional parameter)
以下举个例子

#example 1
#test.sh
#!/bin/bash
set -f   
set -- $*
for each in $*
 do            
  printf "%s\n" $each
done
#result 1
$ bash test.sh "  Hel    world" "djfk kdjf " #本来这里就两个输入参数
Hel
world
djfk
kdjf
----------------------------------------------------------------------------------------------------------------------------------------------------
#example 2
#test.sh
#!/bin/bash
IFS=$'\n'
set -f   
set -- $*
for each in $*
 do            
  printf "%s\n" $each
done
#result 2
$ bash test.sh "  Hel    world" "djfk kdjf " #本来这里就两个输入参数
  Hel    world
djfk kdjf
  1. 正则表达式解析字符串
    以下使用的方法能在大多数场景下和sed交替使用
    注意: 以下方法是依赖了bash本身特性,bash解析过程中会使用操作系统本身解析正则表达式的引擎。如果出于兼容性的考虑,建议使用该方法的时候注意依赖的引擎属于POSIX平台(这是我纯粹的直译,我不是很懂是什么意思,但感觉暂时不影响使用)
    注意: 以下方法仅仅打印正则表达式匹配的第一个结果,如果需要打印所有结果,以下例子需要进行一定的修改
    注意: 我个人觉得该方法的确可以cover大部分的匹配字符串的场景,但使用的时候还是需要小心,需要了解一下 shell 本身的语法和常识

例子如下:

regex() {
    # Usage: regex "string" "regex"
    [[ $1 =~ $2 ]] && printf '%s\n' "${BASH_REMATCH[1]}"
}

解析如下:
3.1. 当使用=~的时候,操作符右边会默认以POSIX的方式解析成对应的正则表达式,当表达式返回结果为0时,代表操作符左右边存在匹配的部分;当返回结果为1时,证明左右两边不匹配;另外当操作符右边正则表达式不合法的时候,该表达式返回结果是2
3.2. 当=~匹配成功后,匹配的结果会存放在${BASH_REMATCH}这个数组中,${BASH_REMATCH[0]}代表了匹配的所有结果

  1. 分割子字符串
    注意: 该方法需要bash脚本是4.0+

例子如下:

split() {
   # Usage: split "string" "delimiter"
   IFS=$'\n' read -d "" -ra arr <<< "${1//$2/$'\n'}"
   printf '%s\n' "${arr[@]}"
}

解析如下:
4.1. 关于IFS和${}变量的解析,可以参考:Shell中的IFS解惑
4.2. read 参数

  • -d 持续读取直到读入 DELIM 变量中的第一个字符,而不是换行符
  • -r 不允许反斜杠转义任何字符
  • -a 将词语赋值给 ARRAY 数组变量的序列下标成员,从零开始

4.3. <<< 可以参考:Shell tutorial 翻译版
4.4. "${1//$2/$'\n'}"表示如果$1中存在$2,就将所有$2全换成$'\n'$'\n'在 shell 脚本中就代表换行符
4.5. "${arr[@]}"表示获取数组里面所有的元素并依旧当成数组处理(待修正)

  1. 改变字符串大小写
    **注意:**该方法需要bash脚本是4.0+

例子如下:

lower() {
    # Usage: lower "string"
    printf '%s\n' "${1,,}"
}
upper() {
    # Usage: upper "string"
    printf '%s\n' "${1^^}"
}
reverse_case() {
    # Usage: reverse_case "string"
    printf '%s\n' "${1~~}"
}

该方法其实记得就可以:

patternexpression
${parameter^^pattern}这种写法会改变 parameter 中所有英文字母的小写为大写
${parameter,,pattern}这种写法会改变 parameter 中所有英文字母的大写为小写
${parameter~~}这种写法会改变parameter中所有英文字母的小写为大写,大写为小写

谢谢观看,未完待续

 类似资料:

相关阅读

相关文章

相关问答