rsync
配列で指定されたいくつかのファイルを繰り返し、ディレクトリ内の他のファイルを削除したいと思います。
私が考えることができる唯一の方法は、を使用し、他のファイルを削除しfind
、rsync
ファイルを上書きしてできるだけ少ない数のファイルをコピーすることです。
次の例では、およびを/tmp/tmp/
除く他のファイルをすべて削除したいと思います。btrfs_x64.efi
iso9660_x64.efi
$ refind_efi_dir='/tmp/tmp/'
$ drivers=('btrfs_x64.efi' 'iso9660_x64.efi')
$ find ${refind_efi_dir}drivers_x64/ "${drivers[@]/#/! -name }" -type f -exec rm -f {} +
拡張を次のコマンドで拡張したいと思います。
$ find /tmp/tmp/drivers_x64/ ! -name btrfs_x64.efi ! -name iso9660_x64.efi -type f -exec rm -f {} +
しかし、次のコマンドを実行しているようです。
$ find /tmp/tmp/drivers_x64/ "! -name btrfs_x64.efi" "! -name iso9660_x64.efi" -type f -exec rm -f {} +
前者を得る方法はありますか?理想的には、配列項目の一部にスペースがある場合にも機能します。
ベストアンサー1
find
はい、ここでは配列の各要素に対して3つのパラメータを生成する必要があります。また、find
パターンが必要なので、正確なファイル名と一致させるには、ワイルドカード演算子(、および)をエスケープする必要が-name
あります。find
*
?
[
\
set -o extendedglob # for (#m)
exclusions=()
for name ($drivers) exclusions+=(! -name ${name//(#m)[?*[\\]/\\$MATCH})
find ${refind_efi_dir}drivers_x64/ $exclusions -type f -exec rm -f {} +
"${array[@]/pattern/replacement}"
各要素に対して置換が実行されると、配列内の要素の数だけ拡張されます。
ここでは-name
ファイルが必要だとします。名前パターンにはを含めないでください。各要素をで置き換えてから分割すること/
ができます。!/-name/element
/
set -o extendedglob # for (#m)
find ${refind_efi_dir}drivers_x64/ \
${(@s[/])${drivers//(#m)[?*[\\]/\\$MATCH}/#/!\/-name\/} \
-type f -exec rm -f {} +
あるいは、とにかく外部コマンドに引数として渡すことはできませんので、$'\0'
notを使用してください。/
set -o extendedglob # for (#m)
find ${refind_efi_dir}drivers_x64/ \
${(@0)${drivers//(#m)[?*[\\]/\\$MATCH}/#/!$'\0'-name$'\0'} \
-type f -exec rm -f {} +
しかし、読みやすさにはあまり役に立ちません...
zsh
ここでは の glob を使ってすべてを表すこともできます。
(cd -P -- $refind_efi_dir && rm -f -- **/^(${(~j[|])drivers})(D.))
ここで、パラメータ拡張フラグは配列j[|]
要素を使用して連結し、グローバル演算子として処理されるようにします。モードが無効になります(このオプションが必要です)。隠しファイルを含みます。$drivers
|
~
|
^
extendedglob
D
.
-type f