Awk

只需將 xml 文件的某些行連接在一起

  • November 18, 2018

我想將此 XML 轉換為僅將某些行連接在一起的位置。這樣我以後可以只對特定行進行 grep。如果這個 XML 使用了屬性,那麼數據已經在 1 行中。我不想用任何 XSLT 來做這件事。grep、sed、awk、xmlstarlet、xpath 會很棒

因此,如果一行包含"<instruction>",那麼我需要抓取接下來的 4 行並將它們全部放在一行中。沒有逗號。如下所示。

這不像這裡發布的問題:它有一個設定的日期模式,開始序列“加入”。

awk '
   /\<instruction\>/ && line {print line; line=""}
   {line = line ? line" "$0 : $0}
   END {print line}
'

這折疊在 UP TO end tag 的行中,但沒有引入 end tag 行本身。

平台將在 Windows 2012R2 伺服器上。將安裝 Gnu 實用程序。文件大小約為 100k。

                       <instruction>
                         <name>AAAAA</name>
                         <value>WHITE</value>
                         <type>0</type>
                       </instruction>
                       <instruction>
                         <name>BBBBB</name>
                         <value>WHITE</value>
                         <type>0</type>
                       </instruction>
                       <instruction>
                         <name>CCCCC</name>
                         <value>WHITE</value>
                         <type>0</type>
                       </instruction>
                     <routing/>
                     <phantom>False</phantom>
                     <AssemblyHistory/>

期望的輸出:(可能已經包裝,但指令元素應該都在 1 行)

<instruction><name>AAAAA</name><value>WHITE</value><type>0</type></instruction> <instruction><name>BBBBB</name><value>WHITE</value><type>0</type></instruction> <instruction><name>CCCCC</name><value>WHITE</value><type>0</type></instruction> <routing/> <phantom>False</phantom> <AssemblyHistory/>

類似範例(格式不正確的 XML)

data line 2
cust:
tommy
smith
123 main
endcust
data line 16
TRACE: error at xy123
cust:
mary 
smith
444 broadway
endcust
LOG: logon tty3
LOG: free memory before gc 33453211
root: ps -ealf  tty0 


data line 2
cust: tommy smith123 main endcust
data line 16
TRACE: error at xy123
cust:mary smith444 broadway endcust
LOG: logon tty3
LOG: free memory before gc 33453211
root: ps -ealf  tty0 

將整個文件複製到標準輸出,不省略任何行。當您找到“cust:”時,可以:1) 加入接下來的 4 行或 2) 加入行直到找到“endcust”

同樣的事情,但這次你不能使用 XML 工具。那麼如果是這種情況,你會如何解決呢?如果最重要的問題是 XML,那麼很好。如果沒有,請使用第二個範例

您可以使用 sed 的範圍運算符來處理您的場景,但在此之前,請確保處理同一行上的標籤和反標籤。同樣不會處理同一行上的多個標籤。

sed -e '
   s/^[[:blank:]]*//
   \|<instruction>.*</instruction>|b
   \|<instruction>|,\|</instruction>|!b
   H;\|</instruction>|!d
   s/.*//;x;s/\n[[:blank:]]*//g;s/^\n//
' input_xml_lookalike_file

我猜你想使用 grep/sed/awk 的原因是你熟悉它們。這並不能使它們成為這項工作的正確工具。僅僅因為你知道如何使用螺絲刀就用螺絲刀敲釘子不是一個聰明的主意。

為此,您需要支持 XML 的工具:XSLT 或 XQuery。(首先,是什麼讓你認為<instruction>標籤永遠不會包含任何空格?並且指令元素的內容總是會超過 4 行?)

我們在 StackOverflow 上收到很多使用者詢問如何生成以特定方式格式化的 XML,這限制了他們對 XML 工具的選擇。當我們問他們為什麼需要這樣做時,答案總是有人編寫了一個應用程序來使用非 XML 感知工具(如 awk、grep 或 Perl)來讀取 XML。如果您這樣做,您將錯過 XML 的全部意義(以及它帶來的所有互操作性優勢)。

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