2020-10-22 最简单的bash下正则表达式用法

  1. 如果需要从字符串或者文件中截取两个以上的变量怎么办?
    很简单:
#!/bin/bash
re="^([^-]+)-(.*)$"
str="ABCDE-123456"
[[ $str =~ $re ]]
var1="${BASH_REMATCH[1]}"
var2="${BASH_REMATCH[2]}"
echo $var1
echo $var2

运行这个脚本,将会回显:
ABCDE
123456

BASH_REMATCH是bash的内置关键字,它是一个数组,用于存储正则表达式中圆括号() 所表达的变量,这跟平时我们使用其他编程语言的时候没有太大的区别,很简单是吧?


  1. 如果匹配的项目不止一个且位置随机,也就是平时我们说的“正则分组”又该怎么办呢?bash没有像python或者go那样有专门的findall或者FindAllStringSubmatch之类方法,但可以通过一个简单算法来完成:
#!/bin/bash

s='1234,2222,abc,311'
regex='([0-9]+)'

while [[ $s =~ $regex ]]; do
        echo "${BASH_REMATCH[1]}"
        s=${s#*"${BASH_REMATCH[1]}"}
done

运行这个脚本,将会回显:
1234
2222
311
这里有一个窍门,每次匹配完的部分将会从s中剔除,然后重新对s进行赋值,直到字符串中再没有可以匹配的项目为止,变相实现了匹配分组功能。
参考资料:
https://unix.stackexchange.com/questions/251013/bash-regex-capture-group


  1. 从文件中读取内容并匹配,这个也很简单,就不再赘述了:
    现有文件ss.json,内容如下:
{
    "server":"127.0.0.1",
    "server_port":8888,
    "local_address":"0.0.0.0",
    "local_port":9999,
    "password":"123abc",
    "timeout":600,
    "method":"aes-128-gcm"
}

我们想将server截取出来,在脚本里我们这么写:

IFS='\n'
cat ss.json | while read line ; do 
  if [[ "$line" =~ \"server\":\"(.+?)\" ]]; then 
    echo IP Address is: ${BASH_REMATCH[1]}
  fi
done

题外话:如果$line这个变量不加双引号,则系统会自动摘掉换行符,将整个文件变成一个长字符串。此处如果加上双引号 "$line" ,输出的时候则是原汁原味按照文件本来的样子输出。

运行脚本,系统将回显:
IP Address is: 127.0.0.1

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容