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

你可能感兴趣的:(2020-10-22 最简单的bash下正则表达式用法)