[英]Circumvent the sed backreference limit \1 through \9
sed手冊明確指出,替代字符串中可用的替代字符串可用的編號為\\ 1到\\ 9。 我正在嘗試解析一個包含10個字段的日志文件。
我為它形成了正則表達式,但第十場比賽(以及之后的任何內容)都無法訪問。
有沒有人有一種優雅的方法來規避KSH中的這種限制(或者我可以移植到shell腳本的任何語言)?
你能用perl -pe 's/(match)(str)/$2$1/g;'
代替sed? 規避反向引用限制的方法是使用除sed之外的其他內容。
另外,我想你可以分兩步進行替換,但我不知道你的模式,所以我無法幫你解決問題。
使用-e拆分流,只要替換的元素與您拆分的組一起使用即可。 當我進行日期分割以便我可以將日期時間重新組合成14位數的字符串時,我不得不將流分割3次。
echo "created: 02/05/2013 16:14:49" | sed -e 's/^\([[:alpha:]]*: \)//' -e 's/\([0-9]\{2\}\)\(\/\)\([0-9]\{2\}\)\(\/\)\([0-9]\{4\}\)\( \)/\5\1\3/' -e 's/\([0-9]\{2\}\)\(\:\)\([0-9]\{2\}\)\(\:\)\([0-9]\{2\}\)/\1\3\5/'
20130205161449
你要求一個shell腳本解決方案 - 這意味着你不僅限於使用sed,對嗎? 大多數shell支持數組,所以也許你可以將該行解析為shell數組變量? 如果需要,您甚至可以多次解析同一行,在每次傳遞中提取不同的信息。
那會嗎?
如果你有GNU awk
,你可以用更多的東西來控制。 為此,您將需要match(source,/regex/,array)
構造。
例:
測試樣本輸入:
echo "$x"
p1=aaa,p2=bb,p3=cc,p4=dd,p5=ee,p6=ff,p7=gg,p8=hh,p9=ii,p10=jj
sed
工作正常,直到\\9
:
echo $x |sed -r 's/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+)(.*)/\1 \2 \3 \4 \5 \6 \7 \8 \9/'
aaa bb cc dd ee ff gg hh ii
當\\10
添加時, sed
打破了,它被認為是\\1
+ 0
。
echo $x |sed -r 's/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+).*p10=([^,]+)(.*)/\1 \2 \3 \4 \5 \6 \7 \8 \9 \10/'
aaa bb cc dd ee ff gg hh ii aaa0
當添加超過9的任何后向引用時添加awk
以進行解救。 這里增加了第10個參考:
echo "$x" |awk '{match($0,/p1=([^,]+).*p2=([^,]+).*p3=([^,]+).*p4=([^,]+).*p5=([^,]+).*p6=([^,]+).*p7=([^,]+).*p8=([^,]+).*p9=([^,]+).*p10=([^,]+)(.*)/,a);print a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10]}'
aaa bb cc dd ee ff gg hh ii jj
考慮一個不需要使用正則表達式反向引用的解決方案。 例如,如果您有一個簡單的字段分隔符,請使用split
,甚至使用awk進行處理而不是perl。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.