2010-11-30 56 views
14

sed手冊明確指出替換字符串中替代字符串的可用反向引用編號爲1到9。我試圖解析一個有10個字段的日誌文件。避開sed反向引用限制 1到 9

我有爲它形成的正則表達式,但第十個匹配(和任何後)無法訪問。

有沒有人有一個優雅的方式來規避KSH(或任何語言,也許我可以移植到shell腳本)的限制?

+2

您可以使用幾乎任何腳本語言,可以讓您爲此編寫一行代碼。 `perl -pe's/yourregexhere/$ 1 $ 2 $ 3 $ 4 $ 5 $ 6 $ 7 $ 8 $ 9 $ 10 /'` – 2010-11-30 20:19:11

+0

很可能您可以使用更簡單的正則表達式,而不需要這麼多的反向引用。如果您顯示一些示例數據和您想要的輸出示例,我們可能會向您展示一種更簡單的方法。 – 2010-11-30 21:10:06

回答

13

你能用perl -pe 's/(match)(str)/$2$1/g;'代替sed嗎?規避反向引用限制的方法是使用sed以外的內容。

另外,我想你可以在兩個步驟中進行替換,但我不知道你的模式,所以我不能幫你解決問題。

3

您正在尋求shell腳本解決方案 - 這意味着您不僅僅限於使用sed,正確嗎?大多數shell支持數組,所以也許你可以將行分析到shell數組變量中?如果需要,您甚至可以多次解析同一行,並在每次傳遞中提取不同位的信息。

會這樣嗎?

1

考慮一個不需要使用正則表達式反向引用的解決方案。例如,如果您有簡單的字段分隔符,請使用split,或者甚至使用awk代替perl處理。

3

使用-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/' 
0

如果你有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 

sed當添加\10爆發,它被認爲是\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 

awk當任何添加了超過9的反向引用被添加時救援。這裏添加了第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