Shell

使用 sed 在 XML 文件中搜尋多個字元串

  • November 2, 2022

我需要過濾一個大文件 XML 並使用多個條件查找字元串。如果 cnisfCF 等於 true 並且 natg_passwordAlreadyResetedPostMigration 為 true,我需要過濾電子郵件。

任何人都可以幫忙嗎?

<customer customer-no="09090909090">
       <credentials>
           <login>teste@gmail.com</login>
           <enabled-flag>true</enabled-flag>
           <password-question/>
           <password-answer/>
       </credentials>
       <profile>
           <salutation/>
           <title/>
           <first-name>teste</first-name>
           <second-name/>
           <last-name>name 1</last-name>
           <suffix/>
           <company-name/>
           <job-title/>
           <email>teste@gmail.com</email>
           <phone-home>542926407485</phone-home>
           <phone-business/>
           <phone-mobile/>
           <fax/>
           <birthday>1999-09-12Z</birthday>
           <gender>2</gender>
           <creation-date>2022-09-19T18:34:45.000Z</creation-date>
           <preferred-locale/>
           <custom-attributes>
               <custom-attribute attribute-id="natg_Newsletter">false</custom-attribute>
               <custom-attribute attribute-id="natg_cfIsCn">false</custom-attribute>
               <custom-attribute attribute-id="natg_cpf">5465465456456</custom-attribute>
               <custom-attribute attribute-id="natg_infContOptIn">false</custom-attribute>
               <custom-attribute attribute-id="natg_optInWP">false</custom-attribute>
               <custom-attribute attribute-id="natg_passwordAlreadyResetedPostMigration">true</custom-attribute>
               <custom-attribute attribute-id="natg_personNumber">116864397</custom-attribute>
               <custom-attribute attribute-id="natg_pushOptIn">false</custom-attribute>
               <custom-attribute attribute-id="natg_rut">456456456</custom-attribute>
           </custom-attributes>
       </profile>

在測試執行以下命令之前,我冒昧地</customer>在數據中添加了缺少的結束標記,並假設您是cnisfCF故意的natg_cfIsCn(屬性和節點名稱區分大小寫)。


使用xmlastarlet

xmlstarlet select --template \
   --match '//profile' \
   --match 'self::node()[custom-attributes/custom-attribute[@attribute-id="natg_cfIsCn"]="true"]' \
   --match 'self::node()[custom-attributes/custom-attribute[@attribute-id="natg_passwordAlreadyResetedPostMigration"]="true"]' \
   --value-of 'email' -nl file.xml

上述命令將提取輸入文件email中任何節點中的節點值,該節點的子節點分別具有屬性和和值和。profile``custom-attributes/custom-attribute``attribute-id``natg_cfIsCn``natg_passwordAlreadyResetedPostMigration``false``true

這裡的棘手之處在於以可讀的方式呈現命令,因為路徑中涉及的節點的名稱很長。我通過首先匹配//profile路徑然後從那裡縮小結果集的兩個單獨步驟來解決這個問題。

僅使用單個“value-of”XPath 查詢的 select 語句看起來像

xmlstarlet select --template \
   --value-of '//profile[
       custom-attributes/custom-attribute[@attribute-id="natg_cfIsCn"]="true" and 
       custom-attributes/custom-attribute[@attribute-id="natg_passwordAlreadyResetedPostMigration"]="true"
   ]/email' -nl file.xml

如果這看起來更漂亮,那麼就使用它。我相信它們應該是等價的。

請注意,上述命令不會為給定文件生成任何輸出,因為沒有與查詢匹配的數據。

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