我有一個腳本可以逐行讀取日志檔案。我需要提取兩個子字串之間的文本,如果它們存在于我的腳本當前正在閱讀的行中。
例如,如果一行有:
some random text here substring A abc/def/ghi substring B
我需要提取文本abc/def/ghi之間。也就是說substring A,并substring B通過將其存盤在一個變數。我該怎么做呢?
我在 Bash 中查看了這個Extract 子字串,但找不到與我的用例完全匹配的任何內容。
uj5u.com熱心網友回復:
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
示例輸出
abc/def/ghi
從弦的前面修剪的兩種基本形式和從弦的背面修剪的兩種基本形式是:
${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
哪里pattern可以包含通配符,例如'*'和'?'。仔細檢查一下,如果您有任何其他問題,請告訴我。
使用 BASH_REMATCH
BASH_REMATCH是一個包含匹配結果的內部陣列[[ text =~ REGEX ]]。${BASH_REMATCH[0]}是匹配的總文本REGEX,然后${BASH_REMATCH[1..2..etc]}是正則運算式中正則運算式捕獲的匹配部分(...)(您可以提供多個捕獲)
使用上面相同的設定,您可以修改替換引數擴展使用的腳本text以使用
regex="^.*${ssa} ([^ ] ) ${ssb}.*$" ## REGEX to match with (..) capture
[[ $line =~ $regex ]] && echo ${BASH_REMATCH[1]}
其中正則運算式 in$regex將匹配整行,捕獲$ssa和之間的內容$ssb。完整的修改腳本將是:
ssa="substring A" ## substrings to find text between
ssb="substring B"
line="some random text here substring A abc/def/ghi substring B"
regex="^.*${ssa} ([^ ] ) ${ssb}.*$" ## REGEX to match with (..) capture
[[ $line =~ $regex ]] && echo ${BASH_REMATCH[1]}
(相同的輸出)
這兩種方法在man 1 bash 中都有詳細說明。使用適合您所面臨情況的任何一種。我總是發現引數擴展更直觀(并且您可以逐步將文本縮減為您需要的任何內容)。但是,擴展正則運算式匹配的強大功能可以為引數擴展提供強大的替代方案。
uj5u.com熱心網友回復:
我相信你可以這樣做:
var="$(echo "some random text here substring A abc/def/ghi substring B"|grep -oP "substring A \K(.*) (?=\ substring B)")"
# which produces:
echo $var
abc/def/ghi
或者,如果以下 grep 更具可讀性、更易于理解,您也可以使用它:
grep -oP "(?<=substring\ A\ )(.*)(?=\ substring B)"
這與上面的邏輯基本相同。
如果搜索/匹配的字串是 2 個或更多單詞,這也將起作用。
編輯1:
所以現在我明白你試圖通過提取檔案的最后一行來做到這一點,然后進行正則運算式匹配?你可以做:
var="$(tail -n1 file.txt|grep -oP "(?<=substring\ A\ )(.*)(?=\ substring B)")"
如果您確定此檔案的最后一行總是與原始問題中的模式匹配的最后一行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/397180.html
