Sử dụng xmlstarlet để xóa toàn bộ phần tử khớp với giá trị thuộc tính?
Câu hỏi của tôi tương tự với sed - Xóa nút XML có chứa phần tử nhất định - Unix & Linux Stack Exchange . Cố gắng thực hiện các đề xuất ở đó đã khiến tôi bận rộn cả ngày, nhưng tôi không thể hoàn thành công việc, vì vậy tôi đăng một câu hỏi.
Trong một tập lệnh bash, tôi cần xóa toàn bộ <folder>
phần tử khi id
thuộc tính khớp với một giá trị nhất định. Tôi thực sự đang sử dụng nhóm người dùng để thực hiện một phần việc này. Giả sử một người dùng không có trong nhóm folder_a
; thì toàn bộ <folder>
phần tử có thuộc tính id=".Folder_A"
sẽ bị xóa khỏi config.xml. (Tôi cũng xóa thư mục khỏi đĩa.)
Tập lệnh bash của tôi trông như thế này:
#!/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
Lệnh perl không hoạt động. Nó chỉ là một trong nhiều biến thể mà tôi đã thử. Tôi cũng đã thử sed. Tôi muốn sử dụng xmlstarlet hơn, nhưng tôi thậm chí còn gặp nhiều rắc rối hơn với nó.
Chỉnh sửa - Tôi vừa tìm thấy câu trả lời này:https://unix.stackexchange.com/a/339089/393289 Nó đã giúp tôi nghĩ ra điều này:
xml ed -d '//configuration/folder[contains(@id,".Folder_A")]' config.xml
Tôi cảm thấy mình gần gũi hơn bây giờ. (Tôi đã cố gắng tán thành câu trả lời đó nhưng tôi chưa có đủ đại diện.) Tuy nhiên, tôi chưa thể dịch tên thuộc tính thành một biến cơ sở do dấu ngoặc kép hoặc thứ gì khác.
BTW, làm cách nào để thực hiện chỉnh sửa tại chỗ (tương tự như sed -i
lệnh) sau khi tôi bắt đầu hoạt động?
Đây là một tệp config.xml mẫu:
<?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>
Đây là một ví dụ config.xml cho syncthing.
Trả lời
Sử dụng tùy chọn -L
/ --inplace
(xem xml edit --help
) và kết hợp chính xác từ câu trả lời được liên kết:
xml ed -L -d "//configuration/folder[@id=\"$foldername\"]" config.xml