我想拆分字符串,如'substring1 substring2 ONCE [0,10s] substring3'。預期的結果應該是(帶有分隔符 'ONCE [0,10s]'):Bash腳本 - 使用正則表達式分隔符分割字符串
substring1 substring2
substring3
的問題是,在分隔符的數量是可變的,如 'ONCE [0,1s]' 或「ONCE [0 ,3m]'或'一次[0,10d]'等等。
如何在bash腳本中執行此操作?任何想法 ?
謝謝
我想拆分字符串,如'substring1 substring2 ONCE [0,10s] substring3'。預期的結果應該是(帶有分隔符 'ONCE [0,10s]'):Bash腳本 - 使用正則表達式分隔符分割字符串
substring1 substring2
substring3
的問題是,在分隔符的數量是可變的,如 'ONCE [0,1s]' 或「ONCE [0 ,3m]'或'一次[0,10d]'等等。
如何在bash腳本中執行此操作?任何想法 ?
謝謝
你可以使用awk
。指定字段分隔爲:
'ONCE[[]0,[^]]*[]] *'
例如,使用您的樣本輸入:
$ awk -F 'ONCE[[]0,[^]]*[]] *' '{for(i=1;i<=NF;i++){printf $i"\n"}}' <<< "substring1 substring2 ONCE[0,10s] substring3"
substring1 substring2
substring3
的bash:
s='substring1 substring2 ONCE[0,10s] substring3'
if [[ $s =~ (.+)" ONCE["[0-9]+,[0-9]+[smhd]"] "(.+) ]]; then
echo "${BASH_REMATCH[1]}"
echo "${BASH_REMATCH[2]}"
else
echo no match
fi
substring1 substring2
substring3
在OP提供的示例(如以及@GlennJackman和@devnull提供的兩個答案)假設實際的問題本來可以的:
在bash中,如何用換行符替換字符串中正則表達式的匹配項。
這實際上與「使用正則表達式分割字符串」不同,除非您添加約束條件,即該字符串不包含任何換行符。即使如此,它實際上並沒有「分裂」字符串。假定其他進程將使用換行符來分割結果。
一旦問題得到重新解決,解決方案並不具有挑戰性。你可以使用支持正則表達式的任何工具,如sed
:
sed 's/ *ONCE\[[^]]*] */\n/g' <<<"$variable"
(刪除g
,如果你只是想更換第一序列,你可能需要調整正則表達式,因爲它不是很清除所需的約束條件是什麼。)
bash
本身不提供replace all
原始的使用正則表達式,但它確實有「圖案」,如果該選項extglob
設置(這是一些分佈在默認),圖案足以表達圖案,因此您可以使用:
echo "${variable//*()ONCE\[*([^]])]*()/$'\n'}"
同樣,你可以替換隻能通過改變//
到/
發生一次,你可能需要改變模式,以滿足您的具體需求。
這留下了一個問題,即如何使用正則表達式指定的分隔符實際分割bash變量,以便對「split」進行某些定義。一個可能的定義是「以字符串的部分作爲參數來調用函數」;這就是我們在這裏使用了一個:
# Usage:
# call_with_split <pattern> <string> <cmd> <args>...
# Splits string according to regular expression pattern and then invokes
# cmd args string-pieces
call_with_split() {
if [[ $2 =~ ($1).* ]]; then
call_with_split "$1" \
"${2:$((${#2} - ${#BASH_REMATCH[0]} + ${#BASH_REMATCH[1]}))}" \
"${@:3}" \
"${2:0:$((${#2} - ${#BASH_REMATCH[0]}))}"
else
"${@:3}" "$2"
fi
}
例子:
$ var="substring1 substring2 ONCE[0,10s] substring3"
$ call_with_split " ONCE\[[^]]*] " "$var" printf "%s\n"
substring1 substring2
substring3