Shell脚本正则匹配无输出问题:如何按指定正则解析内容?
Bash正则匹配无输出问题排查与解决
问题场景
待解析文本内容:
[OK] AAA.BBBBBB aaabbbcccdddfffed asdadadadadadsada [OK] CCC.KKKKKKK some text here [OK] OKO.II
尝试用正则\[OK\](\s+\w+)\.(\w+)\n([^\[]+)解析,但编写的Bash脚本无任何输出,脚本如下:
#!/bin/bash # Define the text to parse text="[OK] AAA.BBBBBB aaabbbcccdddfffed asdadadadadadsada [OK] CCC.KKKKKKK some text here [OK] OKO.II" # Create an empty list to hold the group lists # Loop through the text and extract all matches regex_pattern="\[OK\](\s+\w+)\.(\w+)\n([^\[]+)" while [[ $text =~ $regex_pattern ]]; do # Create a list to hold the current groups echo "Matched_1: ${BASH_REMATCH[1]}" echo "Matched_2: ${BASH_REMATCH[2]}" echo "Matched_3: ${BASH_REMATCH[3]}" echo "-------------------" done
问题根源
- 正则换行符未被解析:Bash双引号包裹的字符串中,
\n是字面量字符而非实际换行,正则无法匹配文本中的换行。 - 最后一条目无法匹配:最后一个
[OK] OKO.II后没有[开头的内容,([^\[]+)因找不到终止符无法匹配该条目。 - 循环未更新文本:即使匹配成功,脚本会重复匹配同一结果陷入死循环,且未处理剩余文本。
修复后的脚本
#!/bin/bash text="[OK] AAA.BBBBBB aaabbbcccdddfffed asdadadadadadsada [OK] CCC.KKKKKKK some text here [OK] OKO.II" # 用$'...'定义正则,让\n解析为实际换行;第三组用正向预查匹配到下一个[OK]或文本结尾 regex_pattern=$'\[OK\](\s+\w+)\.(\w+)\n([^\[]*(?=\[OK\]|$))' while [[ $text =~ $regex_pattern ]]; do echo "Matched_1: ${BASH_REMATCH[1]}" echo "Matched_2: ${BASH_REMATCH[2]}" # 去除第三组末尾的空行/多余换行 trimmed_match3=$(echo "${BASH_REMATCH[3]}" | sed '/^[[:space:]]*$/d') echo "Matched_3: $trimmed_match3" echo "-------------------" # 移除已匹配的部分,处理剩余文本 text=${text#"${BASH_REMATCH[0]}"} done
修复说明
- 用
$'...'格式定义正则,确保\n被识别为实际换行符。 - 第三组正则
([^\[]*(?=\[OK\]|$))通过正向预查,兼容末尾无后续[OK]的条目。 - 每次匹配后用
${text#"${BASH_REMATCH[0]}"}截断已匹配内容,避免死循环并处理剩余文本。 - 对第三组结果做去空行处理,优化输出格式。
内容的提问来源于stack exchange,提问作者Mircea
相关产品推荐
相关产品推荐

