Bash
使用 xmlstarlet 刪除與屬性值匹配的整個元素?
我的問題類似於sed - Delete XML node contains certain element - Unix & Linux Stack Exchange。試圖實施那裡的建議讓我整天忙碌,但我沒有設法讓任何工作,所以我發布了一個問題。
在 bash 腳本中,當屬性與給定值匹配時,我需要刪除整個
<folder>
元素。id
我實際上正在使用使用者組來完成其中的一部分。假設使用者不在組中folder_a
;然後應該從 config.xml 中刪除具有屬性的整個<folder>
元素。id=".Folder_A"
(我也從磁碟中刪除了該文件夾。)我的 bash 腳本如下所示:
#!/bin/bash grouplist=$(groups $theuser); for foldername in '.Folder_A' '.Folder_B'; do grpnm="${foldername,,}"|sed -e 's/^.//' if ! [[ $grouplist =~ ${grpnm} ]]; then perl -0777 -pe "s|(<folder.*?</folder>)|$1=~ /id=\"$foldername\"/?"":$1|gse" config.xml > config.xml rm -fr "$foldername" else echo "permitting access to ${foldername}" fi done
perl 命令不起作用。它只是我嘗試過的眾多變體之一。我也試過sed。我更喜歡使用 xmlstarlet,但我遇到了更多麻煩。
編輯- 我剛剛找到了這個答案:https ://unix.stackexchange.com/a/339089/393289 它幫助我想出了這個:
xml ed -d '//configuration/folder[contains(@id,".Folder_A")]' config.xml
我覺得我現在更接近了。(我試圖支持該答案,但我還沒有足夠的代表。)但是,由於引號或其他原因,我還無法將屬性名稱轉換為 bash 變數。
sed -i
順便說一句,一旦我讓它工作,我如何讓它執行就地編輯(類似於命令)?這是一個範例 config.xml 文件:
<?xml version="1.0"?> <configuration version="32"> <folder id=".Folder_A" label=".Folder_A" path="~/Sync/.Folder_A" type="sendreceive" rescanIntervalS="3600" fsWatcherEnabled="true" fsWatcherDelayS="10" ignorePerms="false" autoNormalize="true"> <filesystemType>basic</filesystemType> <device id="123ABC" introducedBy=""> <encryptionPassword/> </device> <device id="987ZYX" introducedBy=""> <encryptionPassword/> </device> <minDiskFree unit="">0</minDiskFree> <versioning> <cleanupIntervalS>0</cleanupIntervalS> </versioning> <copiers>0</copiers> <disableSparseFiles>false</disableSparseFiles> <disableTempIndexes>false</disableTempIndexes> <paused>false</paused> <weakHashThresholdPct>25</weakHashThresholdPct> <markerName>.stfolder</markerName> </folder> <folder id=".Folder_B" label="Corporate (.Folder_B)" path="~/Sync/.Folder_B" type="sendreceive" rescanIntervalS="3600" fsWatcherEnabled="true" fsWatcherDelayS="5" ignorePerms="true" autoNormalize="false"> <filesystemType>basic</filesystemType> <device id="123ABC" introducedBy=""> <encryptionPassword/> </device> <device id="987ZYX" introducedBy=""> <encryptionPassword/> </device> <minDiskFree unit="">0</minDiskFree> <versioning> <cleanupIntervalS>0</cleanupIntervalS> </versioning> <copiers>0</copiers> <disableSparseFiles>false</disableSparseFiles> <disableTempIndexes>false</disableTempIndexes> <paused>false</paused> <weakHashThresholdPct>25</weakHashThresholdPct> <markerName>.stfolder</markerName> </folder> <device id="123ABC" name="laptop" compression="always" introducer="false" skipIntroductionRemovals="false" introducedBy=""> <paused>false</paused> <autoAcceptFolders>true</autoAcceptFolders> <maxSendKbps>0</maxSendKbps> <maxRecvKbps>0</maxRecvKbps> <maxRequestKiB>0</maxRequestKiB> <untrusted>false</untrusted> </device> <device id="987ZYX" name="desktop" compression="always" introducer="false" skipIntroductionRemovals="false" introducedBy=""> <paused>false</paused> <autoAcceptFolders>true</autoAcceptFolders> <maxSendKbps>0</maxSendKbps> <maxRecvKbps>0</maxRecvKbps> <maxRequestKiB>0</maxRequestKiB> <untrusted>false</untrusted> </device> <gui enabled="true" tls="true" debugging="false"> <address>127.0.0.1:8384</address> <apikey>98qewr0qe9r</apikey> <theme>default</theme> </gui> <ldap/> <options> <listenAddress></listenAddress> <maxSendKbps>0</maxSendKbps> <maxRecvKbps>0</maxRecvKbps> <reconnectionIntervalS>60</reconnectionIntervalS> <relaysEnabled>false</relaysEnabled> <relayReconnectIntervalM>10</relayReconnectIntervalM> <startBrowser>false</startBrowser> <urAccepted>-1</urAccepted> <urSeen>3</urSeen> <urUniqueID/> <urPostInsecurely>false</urPostInsecurely> <urInitialDelayS>1800</urInitialDelayS> <restartOnWakeup>true</restartOnWakeup> <upgradeToPreReleases>false</upgradeToPreReleases> <keepTemporariesH>24</keepTemporariesH> <cacheIgnoredFiles>false</cacheIgnoredFiles> <progressUpdateIntervalS>5</progressUpdateIntervalS> <limitBandwidthInLan>false</limitBandwidthInLan> <overwriteRemoteDeviceNamesOnConnect>false</overwriteRemoteDeviceNamesOnConnect> <tempIndexMinBlocks>10</tempIndexMinBlocks> <trafficClass>0</trafficClass> <defaultFolderPath>~/Sync/</defaultFolderPath> <maxFolderConcurrency>0</maxFolderConcurrency> <crashReportingEnabled>false</crashReportingEnabled> <databaseTuning>auto</databaseTuning> <maxConcurrentIncomingRequestKiB>0</maxConcurrentIncomingRequestKiB> <announceLANAddresses>false</announceLANAddresses> <sendFullIndexOnUpgrade>false</sendFullIndexOnUpgrade> </options> </configuration>
這是syncthing 的config.xml 範例。
使用
-L
/--inplace
選項(請參閱xml edit --help
)和連結答案中的完全匹配:xml ed -L -d "//configuration/folder[@id=\"$foldername\"]" config.xml
使用
xq
(yq
來自https://kislyuk.github.io/yq/的一部分):xq -x --arg id "$foldername" 'del(.configuration.folder[] | select(."@id" == $id))' config.xml
使用
-i
or--in-place
選項進行就地編輯。