我有下一個代碼:
line="95:p1=a b c 95:p2=d e 96:p1=a b c 96:p2=d e"
for l in $line; do
echo $l
done
我得到了下一個:
95:p1=a
b
c
95:p2=d
e
96:p1=a
b
c
96:p2=d
e
但實際上a b c是我的業務中的一個完整字串,所以如果可能的話,我可以通過一些方式獲得下一步?
95:p1=a b c
95:p2=d e
96:p1=a b c
96:p2=d e
uj5u.com熱心網友回復:
第一種解決方案:使用您顯示的示例和嘗試,請嘗試以下awk代碼。用 GNU 撰寫和測驗awk。
這是使用的正則運算式的在線演示。
echo "$line"
95:p1=a b c 95:p2=d e 96:p1=a b c 96:p2=d e
awk -v RS='[0-9]{2}:p[0-9]=[a-zA-Z] [a-zA-Z]( [a-zA-Z]|$)*' 'RT{print RT}' <<<"$line"
顯示樣本的輸出如下:
95:p1=a b c
95:p2=d e
96:p1=a b c
96:p2=d e
第二種解決方案:對于任何 POSIX,awk請嘗試以下awk代碼:
awk '
{
while(match($0,/[0-9]{2}:p[0-9]=[a-zA-Z] [a-zA-Z]( [a-zA-Z]|$)*/)){
print substr($0,RSTART,RLENGTH)
$0=substr($0,RSTART RLENGTH)
}
}
' <<<"$line"
uj5u.com熱心網友回復:
用 bash
read -ra f <<<"$line" # split the string into words
n=${#f[@]}
i=0
lines=()
while ((i < n)); do
l=${f[i ]}
until ((i == n)) || [[ ${f[i]} =~ ^[0-9] : ]]; do
l =" ${f[i ]}"
done
lines =( "$l" )
done
declare -p lines
輸出
declare -a lines=([0]="95:p1=a b c" [1]="95:p2=d e" [2]="96:p1=a b c" [3]="96:p2=d e")
現在你可以做
for l in "${lines[@]}"; do
do_something_with "$l"
done
或者sed, 并使用內置的 bash 捕獲行mapfile
mapfile -t lines < <(sed -E 's/ ([0-9] :)/\n\1/g' <<< "$line")
uj5u.com熱心網友回復:
您不能使用常規引數執行此操作。如果您想要一個可以包含空格的字串集合,請使用陣列。
line=("95:p1=a b c" "95:p2=d e" "96:p1=a b c" "96:p2=d e")
for l in "${line[@]}"; do
echo "$l"
done
否則,您將需要某種方法來區分“文字”空格和“定界符”空格。(也許后者后面跟著<num>:,但是使用正則運算式實作該邏輯并非易事bash。使用功能更強大的語言而不是嘗試在 中執行此操作可能會更好bash。)
uj5u.com熱心網友回復:
echo "${line}" | mawk 'BEGIN { FS=RS="^$"(ORS="") } gsub(" [^ :] :","\1&") gsub("\1.","\n")^_'
95:p1=a b c
95:p2=d e
96:p1=a b c
96:p2=d e
uj5u.com熱心網友回復:
如果您grep支持-P(PCRE) 選項,請嘗試:
grep -Po "\d :.*?(?=(?:\s*\d :|$))" <<< "$line"
輸出:
95:p1=a b c
95:p2=d e
96:p1=a b c
96:p2=d e
正則運算式的解釋\d :.*?(?=(?:\s*\d :|$)):
\d :匹配后跟冒號的數字。它將匹配95:或96:。.*?(?=pattern)匹配后跟 . 的最短字符序列pattern。(?=pattern)是一個未包含在數學結果中的前瞻斷言。- 以上
pattern描述為或(?:\s*\d :|$)的替代 。前者匹配下一個專案的開始部分。before 匹配零個或多個空格字符,從匹配的結果中修剪空格。digits followed by a colonend of the string\s*\d
如果你想遍歷分割的子串,你可以說:
while IFS= read -r i; do
echo "$i" # or whatever you want to do with "$i"
done < <(grep -Po "\d :.*?(?=(?:\s*\d :|$))" <<< "$line")
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/503783.html
