Bash

awk:將行更改為使用命令解析的自身。多行文字

  • February 5, 2021

我試圖回答一個問題。它涉及使用命令recode。該命令必須解析特定的行,而其餘部分保持不變。該文件是一個xml文件。例子:

   <ITEM_ID>foo</ITEM_ID>
   <PRODUCTNAME>bar</PRODUCTNAME>
   <DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
   <URL>bar</URL>
   <IMGURL>foo</IMGURL>
   <IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE>

所需的輸出應該是:

   <ITEM_ID>foo</ITEM_ID>
   <PRODUCTNAME>bar</PRODUCTNAME>
   <DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
   <URL>bar</URL>
   <IMGURL>foo</IMGURL>
   <IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE>

注意:該命令recode按預期工作。避免標籤的轉換DESCRIPTION可以稍後解決,不是問題的一部分。

應該更改的行是以 開頭的行<DESCRIPTION>

awk仍然很糟糕,預期的命令是這樣的:

awk '/<DESCRIPTION>/ { $0 = print $0 "| recode ..html" }1' foo.txt

這當然行不通。

我應該如何做到這一點?

您需要使用 awkgetline將輸出讀入變數。您還需要正確設置區域設置,以便重新編碼按預期工作。嘗試這個:

$ LC_ALL=C gawk '/DESCRIPTION/{
       "echo \""$0"\" | recode ..html" | getline ff; print ff
      }' file 
   <DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>

假設文件格式正確,有一些根節點root……

$ cat file.xml
<root>
   <ITEM_ID>foo</ITEM_ID>
   <PRODUCTNAME>bar</PRODUCTNAME>
   <DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
   <URL>bar</URL>
   <IMGURL>foo</IMGURL>
   <IMGURL_ALTERNATIVE></IMGURL_ALTERNATIVE>
</root>

然後,

$ xmlstarlet ed -u '/root/DESCRIPTION' -v "$( xmlstarlet sel -t -c '/root/DESCRIPTION/*' file.xml )" file.xml
<?xml version="1.0"?>
<root>
 <ITEM_ID>foo</ITEM_ID>
 <PRODUCTNAME>bar</PRODUCTNAME>
 <DESCRIPTION><p>foo</p><p> </p><p> </p></DESCRIPTION>
 <URL>bar</URL>
 <IMGURL>foo</IMGURL>
 <IMGURL_ALTERNATIVE/>
</root>

這裡發生的xmlstarlet sel是用於提取節點下/root/DESCRIPTION節點的副本。這就是這樣xmlstarlet sel -t -c '/root/DESCRIPTION/*' file.xml做的,它返回字元串<p>foo</p><p> </p><p> </p>

/root/DESCRIPTION然後通過命令將該字元串用作節點的新文本值xmlstarlet ed。新值來自命令替換。

請注意,該值會自動進行 XML 編碼。

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