LoginSignup
6
7

More than 1 year has passed since last update.

子ディレクトリの中も含め、あるパターンに一致するファイルのみコピー(rsync)する

Last updated at Posted at 2018-12-03

ハードディスクにある特定のファイルのみ(様々なディレクトリに分散している)を
別のディレクトリに移したいということがあり、
以外に苦戦したのでここに方法を記載する。

rsync

単純にファイルのコピーだけならscpでもいいが、ファイルの所有者やタイムスタンプなども保持したまま
コピーするなら、rsyncを使う。

excludeオプション

Usage : exclude="PATTERN"

そのパターンにマッチするファイル、ディレクトリを除外する。
(*,??)などのワイルドカード指定も可。

example
rsync -avPh --exclude="*.mp3" dir1/ dir2/

これで、dir1/の中にある.mp3ファイル以外のファイルがコピー(同期)される。

includeオプション

Usage : include="PATTERN"

そのパターンにマッチするファイル、ディレクトリを除外させない
*,??などのワイルドカード指定も可。

しかし、

example
rsync -avPh --inlude="*.mp3" dir1/ dir2/

とすると、dir1/の中にある.mp3ファイルのみがコピーされるのではなく、
dir1/のなかのファイルが全てコピーされてしまう。
さらに直下のディレクトリのみしか判定しなかったりと、思ったとおりに動かない。

includeexcludeと併用する

はじめに正解を書くと、

example
rsync -avPh --include="/*" --include="*.mp3" --exclude="*" dir1/ dir2/

となる。

一つずつオプションの解説をする。

  • --include="/*"

    • 現ディレクトリだけでなく、子ディレクトリ(それより深いディレクトリも含め)対象とする。
  • --include="*.mp3"

    • コピーしたいファイルのパターンを指定。(今回はmp3
  • --exclude="*"

    • includeしているもの以外を除外する。

また、--include="*.mp3 --include="*.wav" などとすることで複数のパターンでも指定できる。

FYI include,excludeには順序がある。

example(wrong)
rsync -avPh --exclude="*" --include="/*" --include="*.mp3" dir1/ dir2/

とすると、何もコピーされない。

これは、include,excludeには先頭から順に適用されるという特性があるためである。
--include="/*"は、除外させないというオプションであり、上の例だと、

1. exclude="*"で全てを除外
2. includeしたいけどなにもない
3. 以下同様

という処理になっている。

正解の例だと
rsync -avPh --include="/*" --include="*.mp3" --exclude="*" dir1/ dir2/)、

  1. include="/*"で子ディレクトリ以下も対象にし、
  2. include="*.mp3"で.mp3ファイルは除外されないようにしてから、
  3. exclude="*"で除外されないようにしたファイル以外を除外している。

という処理のため、うまくいく。

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7