Bash
awk:將行更改為使用命令解析的自身。多行文字
我試圖回答一個問題。它涉及使用命令
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
這當然行不通。
我應該如何做到這一點?
您需要使用 awk
getline
將輸出讀入變數。您還需要正確設置區域設置,以便重新編碼按預期工作。嘗試這個:$ 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 編碼。