Bash
如何使用 ksh 中的關鍵字 grep xml 文件中的 xml 塊
我有一個文件 Sample.xml,其中包含很多服務,結構看起來像這樣
筆記:
- 我無法使用任何 XML 解析器工具,因為我沒有權限,只讀
- 我的 xmllint 版本不支持 xpath,無法更新,只讀
- 我沒有 xmlstarlet,無法安裝
問題:輸入:隊列名稱
輸出:服務塊
範例輸入:ABC.getme2
需要的輸出:
<service name="GETME2" min="1" max="10" idleTime="300" backend="ABC"> <handlerContainer className="com.abc.xyz.wqere.abcqwere"> <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/> </handlerContainer> <mqListener queue="ABC.getme2" suggExpiry="30" minExpiry="4" maxExpiry="500" copyMessageId="true"/> </service>
XML結構:
<?xml version="1.0" encoding="UTF-8"?> <deploymentconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <configfile>sample.xml</configfile> <exceptionsFilterConfigFile>asdasd.xml</exceptionsFilterConfigFile> <keyInfoConfigFile>asdasd.xml</keyInfoConfigFile> <services> <service name="GETME" min="1" max="10" idleTime="300" backend="ABC"> <handlerContainer className="com.abc.xyz.wqere.abcqwere"> <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/> </handlerContainer> <mqListener queue="ABC.getme" suggExpiry="30" minExpiry="4" maxExpiry="500" copyMessageId="true"/> </service> <service name="GETME2" min="1" max="10" idleTime="300" backend="ABC"> <handlerContainer className="com.abc.xyz.wqere.abcqwere"> <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/> </handlerContainer> <mqListener queue="ABC.getme2" suggExpiry="30" minExpiry="4" maxExpiry="500" copyMessageId="true"/> </service> . . . .a lot of services like this . . . . . . . .a lot of services like this . . . . . . . .a lot of services like this . . . . . . . .a lot of services like this . . . . </services> <batchServices> <batchService name="batch1"> <executor className="com.abc.xyz.qwer.qweqwewqe.ffdsdfsdfsdfsdf" /> </batchService> <batchService name="batch2"> <executor className="com.abc.xyz.qwer.qweqwewqe.zxcsadsad" /> </batchService> . . . .a lot of batch services like this . . . . . . . .a lot of batch services like this . . . . . . . .a lot of batch services like this . . . . . . . .a lot of batch services like this . . . . </batchServices> <timerservices> <timerservice> - a lot of timeservice </timerservices> <connectionPools> <pool> <name>asdasd</name> <driver>oracle.jdbc.driver.OracleDriver</driver> <url>$asdasd_URL</url> <userId>$asdasd_USER</userId> <password>$asdasd_PASSWORD</password> <minConnections>0</minConnections> <maxConnections>10</maxConnections> <poolUrl>jdbc:asdsad:asdasdsad</poolUrl> <testSql>select * from abc</testSql> </pool> . . a lot of pools. . . </connectionpools> </deploymentconfig>
我需要像這樣grep一個xml塊:
<service name="GETME" min="1" max="10" idleTime="300" backend="ABC"> <handlerContainer className="com.abc.xyz.wqere.abcqwere"> <handler className="com.abc.xyz.qweqweqwe.werwerwerwer"/> </handlerContainer> <mqListener queue="ABC.getme" suggExpiry="30" minExpiry="4" maxExpiry="500" copyMessageId="true"/> </service>
我只需要提供隊列名稱
QUEUENAME=INSERT_HERE grep ______________ $QUEUENAME. . .
這是輸出:
Usage : xmllint [options] XMLfiles ... Parse the XML files and output the result of the parsing --version : display the version of the XML library used --debug : dump a debug tree of the in-memory document --shell : run a navigating shell --debugent : debug the entities defined in the document --copy : used to test the internal copy implementation --recover : output what was parsable on broken XML documents --noent : substitute entity references by their value --noout : don't output the result tree --path 'paths': provide a set of paths for resources --load-trace : print trace of all external entites loaded --nonet : refuse to fetch DTDs or entities over network --nocompact : do not generate compact text nodes --htmlout : output results as HTML --nowrap : do not put HTML doc wrapper --valid : validate the document in addition to std well-formed check --postvalid : do a posteriori validation, i.e after parsing --dtdvalid URL : do a posteriori validation against a given DTD --dtdvalidfpi FPI : same but name the DTD with a Public Identifier --timing : print some timings --output file or -o file: save to a given file --repeat : repeat 100 times, for timing or profiling --insert : ad-hoc test for valid insertions --compress : turn on gzip compression of output --html : use the HTML parser --xmlout : force to use the XML serializer when using --html --push : use the push mode of the parser --memory : parse from memory --maxmem nbbytes : limits memory allocation to nbbytes bytes --nowarning : do not emit warnings from parser/validator --noblanks : drop (ignorable?) blanks spaces --nocdata : replace cdata section with text nodes --format : reformat/reindent the input --encode encoding : output in the given encoding --dropdtd : remove the DOCTYPE of the input docs --c14n : save in W3C canonical format (with comments) --exc-c14n : save in W3C exclusive canonical format (with comments) --nsclean : remove redundant namespace declarations --testIO : test user I/O support --catalogs : use SGML catalogs from $SGML_CATALOG_FILES otherwise XML Catalogs starting from file:///etc/xml/catalog are activated by default --nocatalogs: deactivate all catalogs --auto : generate a small doc on the fly --xinclude : do XInclude processing --noxincludenode : same but do not generate XInclude nodes --loaddtd : fetch external DTD --dtdattr : loaddtd + populate the tree with inherited attributes --stream : use the streaming interface to process very large files --walker : create a reader and walk though the resulting doc --pattern pattern_value : test the pattern support --chkregister : verify the node registration code --relaxng schema : do RelaxNG validation against the schema --schema schema : do validation against the WXS schema --schematron schema : do validation against a schematron --sax1: use the old SAX1 interfaces for processing --sax: do not build a tree but work just at the SAX level Libxml project home page: http://xmlsoft.org/ To report bugs or get some help check: http://xmlsoft.org/bugs.html
這是版本
xmllint: using libxml version 20626
如果你使用的是最新
ksh
的——我指的是最近的版本ksh93
——你實際上可以使用它。ksh93
支持複合變數類型(有點像 C 結構)或 XML 節點樹。目前它本身並不支持 XML——儘管我相信它是計劃好的——但它json
現在確實支持。我使用了一些免費的線上轉換器來獲取
json
您的樣本輸出。儘管如此,在稍微清理一下樣本之後*(順便說一下,</connectionpools>中的****p應該是大寫的)*我可以這樣做:print -j queue.services.[@name]
……並獲得了……
GETME
我也可以這樣做:
print -j queue.services[1].[@name]
……取而代之……
GETME2
在連結的轉換站點上,我必須選擇製表符分隔以防止它粘在很多不間斷的空間中,但除此之外,它似乎還可以。當然,您可以輕鬆地在本地使用一些工具來進行類似的轉換。
無論如何,
ksh
您可以json
像我一樣將其複製到剪貼板後在樹中閱讀,例如:read -m json queue <<<"$(xsel -bo)"
之後,我可以像查看整個結構一樣…
print -j queue
…列印…
{ "batchServices": [ { "@name": "batch1", "executor": { "@className": "com.abc.xyz.qwer.qweqwewqe.ffdsdfsdfsdfsdf" } }, { "@name": "batch2", "executor": { "@className": "com.abc.xyz.qwer.qweqwewqe.zxcsadsad" } } ], "configfile": "sample.xml", "connectionPools": [ { "driver": "oracle.jdbc.driver.OracleDriver", "maxConnections": "10", "minConnections": "0", "name": "asdasd", "password": "$asdasd_PASSWORD", "poolUrl": "jdbc:asdsad:asdasdsad", "testSql": "select * from abc", "url": "$asdasd_URL", "userId": "$asdasd_USER" } ], "exceptionsFilterConfigFile": "asdasd.xml", "keyInfoConfigFile": "asdasd.xml", "services": [ { "@backend": "ABC", "@idleTime": "300", "@max": "10", "@min": "1", "@name": "GETME", "handlerContainer": { "@className": "com.abc.xyz.wqere.abcqwere", "handler": { "@className": "com.abc.xyz.qweqweqwe.werwerwerwer" } }, "mqListener": { "@copyMessageId": "true", "@maxExpiry": "500", "@minExpiry": "4", "@queue": "ABC.getme", "@suggExpiry": "30" } }, { "@backend": "ABC", "@idleTime": "300", "@max": "10", "@min": "1", "@name": "GETME2", "handlerContainer": { "@className": "com.abc.xyz.wqere.abcqwere", "handler": { "@className": "com.abc.xyz.qweqweqwe.werwerwerwer" } }, "mqListener": { "@copyMessageId": "true", "@maxExpiry": "500", "@minExpiry": "4", "@queue": "ABC.getme2", "@suggExpiry": "30" } } ] }
正如上面評論中提到的,
xmllint
可以像這樣使用xmllint --xpath '//service/[@name="GETME"]' Sample.xml
該選項至少從 libxml 版本 20903 開始可用。
可以在此處找到有關 xpath 語法的入門:http: //www.w3schools.com/xpath/xpath_syntax.asp或更權威的https://www.w3.org/Consortium/Offices/Presentations/XSLT_XPATH/#(23)