Manipuluji s velkým množstvím souborů XML roztroušených ve vnořené adresářové struktuře.
Zkusil jsem následující:
$ find . -name "*.xml" -type f | xargs -- xmllint --format
Problém je v tom, že generuje naformátovaný výstup XML na obrazovce, ale nemění soubor.
Jak mohu změnit tento příkaz tak, aby se změnil skutečný obsah souboru?
Přijatá odpověď:
To lze provést z find
přímo pomocí -exec
:
find . -name "*.xml" -type f -exec xmllint --output '{}' --format '{}' \;
Co je předáno do -exec
bude vyvoláno jednou pro každý nalezený soubor s parametry šablony {}
nahrazen aktuálním názvem souboru. \;
na konci příkazu find právě ukončí řádek.
Použití xargs
není v tomto případě opravdu nutné, protože musíme vyvolat xmllint
jednou na soubor, protože název vstupního i výstupního souboru musí být specifikován ve stejném volání.
xargs
by bylo potřeba, pokud by příkaz přesměrovaný z find pracoval na více souborech současně a tento seznam byl dlouhý. V tomto případě to nemůžete udělat, protože musíte předat jeden název souboru do --output
možnost xmllint
. Bez xargs
pokud zpracováváte velké množství souborů, můžete skončit s chybou „Příliš dlouhý seznam argumentů“. xargs
také podporuje nahrazení souborů řetězcem -I
možnost:
find . -name "*.xml" -type f | xargs -I'{}' xmllint --output '{}' --format '{}'
Udělalo by to totéž jako find -exec
příkaz výše. Pokud některá z vašich složek obsahuje liché znaky v podobných mezerách, budete muset použít -0
možnosti find
a xargs
. Ale pomocí xargs
s -I
znamená volbu -L 1
což znamená, že stejně zpracujte pouze 1 soubor najednou, takže můžete také přímo použít find
s -exec
.