Gunakan xmlstarlet untuk menghapus seluruh elemen yang cocok dengan nilai atribut?
Pertanyaan saya mirip dengan sed - Hapus node XML yang mengandung elemen tertentu - Unix & Linux Stack Exchange . Mencoba menerapkan saran di sana telah membuat saya sibuk sepanjang hari, tetapi saya belum berhasil membuat apa pun berfungsi, jadi saya memposting pertanyaan.
Dalam skrip bash, saya perlu menghapus seluruh <folder>
elemen saat id
atribut cocok dengan nilai yang diberikan. Saya sebenarnya menggunakan grup pengguna untuk melakukan sebagian dari ini. Katakanlah seorang pengguna tidak ada dalam grup folder_a
; maka seluruh <folder>
elemen dengan atribut id=".Folder_A"
harus dihapus dari config.xml. (Saya juga menghapus folder dari disk.)
Skrip bash saya terlihat seperti ini:
#!/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
Perintah perl tidak berfungsi. Ini hanyalah salah satu dari banyak varian yang telah saya coba. Saya juga mencoba sed. Saya lebih suka menggunakan xmlstarlet, tetapi saya mengalami lebih banyak masalah dengannya.
Edit - Saya baru saja menemukan jawaban ini:https://unix.stackexchange.com/a/339089/393289 Ini membantu saya menemukan ini:
xml ed -d '//configuration/folder[contains(@id,".Folder_A")]' config.xml
Saya merasa seperti saya lebih dekat sekarang. (Saya mencoba untuk memberi suara positif pada jawaban itu tetapi saya belum memiliki cukup perwakilan.) Namun, saya belum dapat menerjemahkan nama atribut ke dalam variabel bash karena tanda kutip atau hal lain.
BTW, bagaimana cara membuatnya melakukan pengeditan di tempat (mirip dengan sed -i
perintah) setelah saya membuatnya berfungsi?
Berikut ini contoh file 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>
Ini adalah contoh config.xml untuk syncthing.
Jawaban
Gunakan opsi -L
/ --inplace
(lihat xml edit --help
) dan pencocokan persis dari jawaban terkait:
xml ed -L -d "//configuration/folder[@id=\"$foldername\"]" config.xml