Ric*_*ois 3 bash shell substring
我有一个逐行读取日志文件的脚本。我需要提取两个子字符串之间的文本(如果它们存在于我的脚本当前正在读取的行中)。
例如,如果一行有:
some random text here substring A abc/def/ghi substring B
Run Code Online (Sandbox Code Playgroud)
我需要通过将其存储在变量中来提取和abc/def/ghi之间的文本。我该怎么做呢?substring Asubstring B
我查看了Bash 中的 Extract substring,但找不到任何与我的用例完全匹配的内容。
Bash 提供了带有子字符串删除功能的参数扩展"substring A",允许您从前面修剪,然后"substring B"从后面修剪留下"abc/def/ghi". 例如,您可以执行以下操作:
ssa="substring A" ## substrings to find text between
ssb="substring B"
line="some random text here substring A abc/def/ghi substring B"
text="${line#*${ssa}}" ## trim through $ssa from the front (left)
text="${text%${ssb}*}" ## trim through $ssb from the back (right)
echo $text ## output result
Run Code Online (Sandbox Code Playgroud)
示例输出
abc/def/ghi
Run Code Online (Sandbox Code Playgroud)
从琴弦前面修剪的两种基本形式和从琴弦背面修剪的两种基本形式是:
${var#pattern} # Strip shortest match of pattern from front of $var
${var##pattern} # Strip longest match of pattern from front of $var
${var%pattern} # Strip shortest match of pattern from back of $var
${var%%pattern} # Strip longest match of pattern from back of $var
Run Code Online (Sandbox Code Playgroud)
其中pattern可以包含通配字符,例如'*'和'?'。仔细检查一下,如果您还有任何疑问,请告诉我。
使用 BASH_REMATCH
BASH_REMATCH是一个内部数组,包含匹配的结果[[ text =~ REGEX ]]。${BASH_REMATCH[0]}是匹配的总文本REGEX,然后${BASH_REMATCH[1..2..etc]}是正则表达式捕获的正则表达式内的匹配部分(...)(您可以提供多个捕获)
使用与上面相同的设置,您可以修改替换参数扩展使用的脚本来text使用
${var#pattern} # Strip shortest match of pattern from front of $var
${var##pattern} # Strip longest match of pattern from front of $var
${var%pattern} # Strip shortest match of pattern from back of $var
${var%%pattern} # Strip longest match of pattern from back of $var
Run Code Online (Sandbox Code Playgroud)
其中的正则表达式将匹配捕获和$regex之间内容的整行。完整修改后的脚本将是:$ssa$ssb
regex="^.*${ssa} ([^ ]+) ${ssb}.*$" ## REGEX to match with (..) capture
[[ $line =~ $regex ]] && echo ${BASH_REMATCH[1]}
Run Code Online (Sandbox Code Playgroud)
(相同的输出)
这两种方法在man 1 bash中有完整的解释。使用适合您所面临情况的任何一个。我总是发现参数扩展更直观(并且您可以逐渐将文本缩减为您需要的任何内容)。然而,扩展正则表达式匹配的强大功能可以为参数扩展提供强大的替代方案。