我有一個包含大量 XML 檔案的目錄,這些檔案的格式不完全相同,但我所追求的檔案包含 3 個相同的必填欄位。我需要知道每個庫的 SNPID,因為它們必須是唯一的。為此,我需要列出每個及其 ID 值。
首先,我只需要從“PoweredBy”欄位中包含 value="Kontakt" 的檔案中獲取結果。然后對于每個我需要將名稱、SNPID 和 RegKey 列印到 3 列 CSV 中。例如。神秘主義 | 第547章 最佳服務 - Mystica
XML 檔案如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<ProductHints spec="1.0.16">
<Product version="2">
<UPID>70026fd5-8f6f-429e-b891-12c2f94bc566</UPID>
<Name>Mystica</Name>
<Type>Content</Type>
<NKSEnabled minVersion="1.1.0.0">true</NKSEnabled>
<Relevance maxVersion="1.0.9.0" minVersion="1.0.0.0">
<Application minVersion="5.0.0.0" nativeContent="true">kontakt</Application>
</Relevance>
<Relevance minVersion="1.1.0.0">
<Application minVersion="5.8.0.0" nativeContent="true">kontakt</Application>
<Application minVersion="2.6.5.0">maschine</Application>
<Application minVersion="1.8.2.0">kkontrol</Application>
</Relevance>
<PoweredBy>Kontakt</PoweredBy>
<Visibility maxVersion="1.0.9.0" minVersion="1.0.0.0" target="Standalone">1</Visibility>
<Company>Best Service</Company>
<AuthSystem>RAS2</AuthSystem>
<SNPID>547</SNPID>
<RegKey>Best Service - Mystica</RegKey>
<Icon>bestservice</Icon>
<ProductSpecific>
<HU>496B8CF4F8B1402C4A6650214DF2514C</HU>
<JDX>C9A2B6D9549FD159D8A3CFF054AAE934C2AC849EC74827847288DF07577A8F22</JDX>
<Visibility type="Number">3</Visibility>
</ProductSpecific>
</Product>
</ProductHints>
我試過了
Computer:~ user$ cd /Library/Application\ Support/Native\ Instruments/Service\ Center
Computer:Service Center
while read -r Name SNPID RegKey
do
echo " "
echo "Name: ${Name}"
echo "SNPID: ${SNPID}"
echo "RegKey: ${RegKey}"
awk -F '[<>]' '{if (FNR%2==1) {printf "%s: ",$3} else {print $3}}'
done
但結果不一致(我知道 bash 不適合決議 XML,但要求非常基本)。
find -name "*.xml" | xargs cat | tr -d "\n" | sed 's/<\/Name>/\n/g' | sed 's/<\/SNPID>/\n/g' | sed 's/<\/RegKey>/: /g' | sed 's/<[^>]*>//g' | egrep "Name:|SNPID:|RegKey:" | sed 's/Name: /---\nName: /g'
也會導致錯誤:查找:非法選項--n
那里有任何 BASH 向導可以幫助我嗎?(如果可能的話,我寧愿使用終端而不安裝其他東西)謝謝
uj5u.com熱心網友回復:
這可能對您有用(GNU sed):
sed -sE '/^\s*<(Name|SNPID|PoweredBy|RegKey)>(.*)<\/\1>\s*$/{s//\1:\2/;H}
$!d;g;/PoweredBy:Kontakt/!d
s/Name:([^\n]*)(.*)/\2\n\1/
s/SNPID:([^\n]*)(.*)/\2|\1/
s/RegKey:([^\n]*)(.*)/\2|\1/
s/.*\n//' file ...
使用選項-s分別處理每個輸入檔案并-E簡化正則運算式。
使用交替,將所需欄位提取到保留緩沖區中。
PoweredBy如果該欄位不包含在檔案末尾,則Kontakt不需要進一步處理。
否則,將保持緩沖區中的欄位格式化為所需的格式并列印結果。
uj5u.com熱心網友回復:
使用sed
$ sed -n '/Name\|SNPID\|RegKey/{s/[^>]*>\([^<]*\).*/\1/;H;d};G;s/\n/ | /g;/^ |/{s/^ | \ | //p}' input_file
Mystica | 547 | Best Service - Mystica
uj5u.com熱心網友回復:
find1. 使用和定位所需檔案grep
grep -l "PoweredBy>Kontakt" $(find . -name "*.xml")
驗證您是否獲得了正確的檔案串列。
2. 從所需檔案中提取資料并格式化資料awk
這個awk腳本,只對需要的檔案一一處理。
awk -F"[><]" '
$2 == "Name" {ret = $3 " | "}
$2 == "SNPID" {ret = ret $3 " | "}
$2 == "RegKey" {print ret $3}
' $(grep -l "PoweredBy>Kontakt" $(find . -name "*.xml"))
awk不使用grep命令的替代方法。
awk -F"[><]" '
$2 == "PoweredBy" && $3 != "Kontakt" {nextfile}
$2 == "Name" {ret = $3 " | "}
$2 == "SNPID" {ret = ret $3 " | "}
$2 == "RegKey" {print ret $3}
' $(find . -name "*.xml")
uj5u.com熱心網友回復:
強烈推薦:不要嘗試使用除了正確的 xml 決議器之外的任何東西來決議 xml。為此,您可以使用 xmlstarlet [編輯以反映以下@Reino 的評論:
xml sel -T -t -m "//ProductHints//Product[PoweredBy="Kontakt"]" -v //SNPID/. --nl -v //Name/. --nl -v //RegKey/. --nl your_file.xml
或者,更簡單的是 xidel:
xidel your_file.xml -e '//ProductHints//Product[PoweredBy="Kontakt"]//(Name,SNPID,RegKey)'
輸出(基于您問題中的示例 xml)應該是:
547
Mystica
Best Service - Mystica
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/466242.html
