Text-Processing

在文件中查找標籤的重複實例

  • April 18, 2019

多個程式碼片段存在於類似於以下內容的文件中:

<blah>Spread the peanut butter <ramout assot="f0123_fun10" bapel="2 or 6"/> on good looking bread <ramout assot="f0123_fun10" bapel="3 or 5"/> that does not have peanut butter <ramout assot="f0123_fun10" bapel="2 or 6"/> already on the bread this that and the other <ramout assot="f0123_fun10" bapel="4"/> with something else.</blah>

我正在嘗試在單個文件中查找 ramout 標記的重複實例。如果存在以下情況:

<ramout assot="f0123_fun10" bapel="2 or 6"/> 

我想知道它是否在開始和結束 blah 標籤中再次重複。

我嘗試了多種方法,但最新的一種方法如下:

grep -Eoi '<blah>.*([[:space:]]<ramout assot).*\1.*</blah>' *.xml | less

它什麼也沒返回。

我也試過:

grep -Eio '<blah>.*([[:space:]]<ramout assot="[a-z][0-9]{5}_fig[0-9]+" bapel="[0-9]+.*)' *.xml

它不包括反向引用,但也不顯示所有結果。看起來這僅顯示一行的結果(不要跨越多行)。

如果我想搜尋可能在或可能不在一行上的東西,我應該使用 sed 嗎?

awk 是一個可行的候選人嗎?我看到並嘗試過: awk ‘/Start pattern/,/End pattern/’ filename 返回了更多結果,但我仍然沒有得到所有結果。

任何能夠找到 a) 整個文件中的所有結果和單獨 b) 在 blah 標籤中重複的所有結果的任何幫助將不勝感激。

預期結果如下所示:

搜尋結果 a) 顯示所有 ramout 結果:

<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="3 or 5"/>
<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="4"/>

搜尋結果 b) 顯示重複結果將顯示:

<ramout assot="f0123_fun10" bapel="2 or 6"/>

使用XMLStarlet(有時安裝為xmlstarlet而不是 just xml)提取相關標籤,然後sort查找uniq重複項:

$ xml sel -t -m '/blah/ramout' -c '.' -nl test.xml | sort | uniq -d
<ramout assot="f0123_fun10" bapel="2 or 6"/>

xml命令將匹配<ramout>標籤下的所有<blah>標籤,並為每個標籤複製標籤,後跟換行符到標準輸出。

sort排序並uniq -dsort.

這樣的事情在我的測試中可以正常工作:

awk -F"/>" -v RS="<ramout assot=" 'NR>1{print RS $1 FS}' file1

echo "Finding Cuplicates:"
awk -F"/>" -v RS="<ramout assot=" 'NR==1{next}seen[$1]++==1{print RS $1 FS}' file1

<ramout assot="f0123_fun10" bapel="2 or 6"/> 
<ramout assot="f0123_fun10" bapel="3 or 5"/> 
<ramout assot="f0123_fun10" bapel="2 or 6"/>
<ramout assot="f0123_fun10" bapel="4"/> 
Finding Cuplicates:              
<ramout assot="f0123_fun10" bapel="2 or 6"/>  

在這裡線上測試

我們利用 awk 功能來聲明自定義記錄分隔符 (RS) 和自定義欄位分隔符 (FS)。以上兩個命令可以組合在一個 awk 中,這只是一個測試。

引用自:https://unix.stackexchange.com/questions/350831