ファイル形式を含むディレクトリの検索とコピー

ファイル形式を含むディレクトリの検索とコピー

サブディレクトリ「Movie Name」を含む「Movies」ディレクトリがあります。各サブディレクトリ「映画名」には、映画ファイル、関連する画像/情報ファイルなどが含まれています。

「.avi」タイプのムービーファイルを含むすべてのディレクトリを外部USBデバイスにコピーしようとしています。

したがって、Directory/subdirectory Aと が含まれている場合は、そのディレクトリとその内容を外部ドライブにコピーしたいと思います。movie.aviposter.jpgmovie.nfo

私はこれを試しました:

find . -name "*.avi" -printf "%h\n" -exec cp {} /share/USBDisk1/Movies/ \;

ただし、ディレクトリとファイルの内容ではなくファイルのみをコピーします。

ベストアンサー1

まず、試みが機能しない理由:-printf "%h\n"filenameのディレクトリ部分を印刷してください.avi。これは-exec後続の操作には影響しません。{}「最後に印刷されたコマンド」を意味するのではなく、printf「検出されたファイルへのパス」を意味します。

コマンドでファイル名のディレクトリ部分を使用するには、cpファイル名を渡す必要がありますcpfindコマンドにはこの機能はありませんが、シェルにはあるので、 make がfind呼び出すシェルを呼び出しますcp

find . -name "*.avi" -exec sh -c 'cp -Rp "${0%/*}" /share/USBDisk1/Movies/' {} \;

ディレクトリをコピーするので-r、 。.cp-p

cp -Rpこの方法では、rsync -aムービーディレクトリをすでにコピーしている場合は、内容が変更されない限り再コピーされません。

あなたのコマンドには、あなたに影響を与える可能性があり、そうでない可能性がある欠陥があります。ディレクトリに複数の.aviファイルが含まれている場合は、複数回コピーされます。ファイルを.avi見つけるよりもディレクトリを見つけてファイルが含まれている場合は、コピーすることをお勧めします.avirsync代わりに、ファイルは再コピーされず、ファイルの存在を確認し続けるためにcpさらに多くの作業が必要になります。rsync

すべてのムービーディレクトリが最上位ディレクトリのすぐ下にある場合、これは必要ではなく、findワイルドカードパターンの単純なループで十分です。

for d in ./*/; do
  set -- "$d/"*.avi
  if [ -e "$1" ]; then
    # there is at least one .avi file in $d
    cp -rp -- "$d" /share/USBDisk1/Movies/
  fi
done

ムービーディレクトリがネストされている場合(たとえばMovies/science fiction/Ridley Scott/Blade Runner、)これは必要ではなく、findワイルドカードパターンの単純なループで十分です。 ksh93またはbash≥4またはzshを実行し、ksh93では最初に実行し、bashでは最初に実行する必要がありset -o globstarます。shopt -s globstarワイルドカードパターンは、**/現在のディレクトリとすべてのサブディレクトリを繰り返し一致させます(bashはサブディレクトリへのシンボリックリンクも通過します)。

for d in ./**/; do
  set -- "$d/"*.avi
  if [ -e "$1" ]; then
    cp -rp -- "$d" /share/USBDisk1/Movies/
  fi
done

おすすめ記事