簡體   English   中英

提取包含帶有sed的特定字符串的XML元素

[英]Extracting XML elements which contains a certain string with sed

我有一個像下面的文件

  <AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="show databases"/>
  <AUDIT_RECORD TIMESTAMP="2013-07-29T17:27:53" NAME="Quit" CONNECTION_ID="12" STATUS="0"/>
  <AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="show grants for root@localhost"/>
  <AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="create table stamp like paper"/>

在這里,每個記錄都以<AUDIT_RECORD開頭,以"/>結尾,並且該記錄可能分布在多行中。

我的要求是顯示如下結果

  <AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="show databases"/>
  <AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="show grants for root@localhost"/>
  <AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="create table stamp like paper"/>

為此,我用了

sed -n "/Query/,/\/>/p" file.txt

但是它將顯示整個文件,包括帶有字符串“ Quit”的記錄。

有人可以幫我嗎? 另外請讓我知道是否可以完全匹配名為“ Query”的字符串(例如grep -w "Query" )。

使用GNU awk,您可以將RS設置為多個字符:

$ cat file
<AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query"
                CONNECTION_ID="10" STATUS="0" SQLTEXT="show databases"/>
<AUDIT_RECORD TIMESTAMP="2013-07-29T17:27:53"
        NAME="Quit" CONNECTION_ID="12" STATUS="0"/>
<AUDIT_RECORD
        TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10"
     STATUS="0" SQLTEXT="show grants for root@localhost"/>
<AUDIT_RECORD
        TIMESTAMP="2013-07-30T17:52:29"
        NAME="Query"
        CONNECTION_ID="10"
        STATUS="0"
        SQLTEXT="create table stamp like paper"/>
$
$ gawk -v RS='\\/>\n' -v ORS= '/Query/{print $0 RT}' file
<AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query"
                CONNECTION_ID="10" STATUS="0" SQLTEXT="show databases"/>
<AUDIT_RECORD
        TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10"
     STATUS="0" SQLTEXT="show grants for root@localhost"/>
<AUDIT_RECORD
        TIMESTAMP="2013-07-30T17:52:29"
        NAME="Query"
        CONNECTION_ID="10"
        STATUS="0"
        SQLTEXT="create table stamp like paper"/>
$
$ gawk -v RS='\\/>\n' -v ORS= '/Query/{$1=$1; print $0 RT}' file
<AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="show databases"/>
<AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="show grants for root@localhost"/>
<AUDIT_RECORD TIMESTAMP="2013-07-30T17:52:29" NAME="Query" CONNECTION_ID="10" STATUS="0" SQLTEXT="create table stamp like paper"/>

我同意@choroba的觀點,即XML解析器是正確的工具。 但是,如果沒有可用的,則可以嘗試以下awk腳本:

awk '/Query/{print RS" "$0}' RS='<AUDIT_RECORD' file

輸入的內容可能是XML。 使用適當的解析器來處理它,尤其是當記錄跨越多行時。 例如, xsh

open file.xml ;
remove //AUDIT_RECORD[not(@NAME="Query")] ;
save :b ;

我建議的sed解決方案:

sed 's/<[^>]*\"Quit\"[^>]*>//' file.txt

對於跨越多行的記錄,請嘗試:

sed '{:q;N;s/\n/ /g;t q}' file.txt | sed 's/<[^>]*\"Quit\"[^>]*>//'

添加換行符RS:

... | sed 's|/>|/>\n|g'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM