- 如果需要从字符串或者文件中截取两个以上的变量怎么办?
很简单:
#!/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的内置关键字,它是一个数组,用于存储正则表达式中圆括号() 所表达的变量,这跟平时我们使用其他编程语言的时候没有太大的区别,很简单是吧?
- 如果匹配的项目不止一个且位置随机,也就是平时我们说的“正则分组”又该怎么办呢?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
- 从文件中读取内容并匹配,这个也很简单,就不再赘述了:
现有文件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
网友评论