`source_dir` 配下にある `*.x` というファイル（同じディレクトリ階層には `*.y`
とか違う拡張子のファイルがあるがそれらを除いて）を、ディレクトリ構造を維持したまま `destnation_dir` にコピーするには、

```

    cd source_dir/
    cp --parent */*/*.x   destnation_dir/
    
```

のようにすると実現できます。

しかしながら、`*.x` がたくさんあるとコマンドラインサイズオーバーでエラーになってしまいます。そのような場合、どうするのがいいのでしょうか？

例えば、

```

    cd source_dir/
    find . -name "*.x" | xargs tar cf - | tar xf - -C destnation_dir/
    
```

のようにしてもできるようですが。
CC BY-SA 4.0
2019-07-12T04:32:49.867
56585
2019-07-15T13:22:09.073
2019-07-14T14:32:05.770
3061
24431
question
linux command-line
Linuxで大量のファイルをディレクトリ構造を維持したままコピーしたい
[GNU install](https://linuxjm.osdn.jp/html/gnumaniak/man1/install.1.html)
コマンドはどうでしょうか。`cp` コマンドと似ていますが、`-D` オプションを指定することで移動元のディレクトリ階層を自動的に作成してくれます。

```

    $ find source_dir -name \*.x | xargs -I '{}' install -vD '{}' 'destnation_dir/{}'
    
```

上記コマンド例ではファイル属性（更新日、アクセス権など）のコピーは考慮していません。適宜オプションを追加してください
CC BY-SA 4.0
2019-07-13T12:52:17.287
56626
2019-07-13T12:52:17.287
2391
56585
answer
特定条件のファイルを相対パスを維持してコピーをしたい場合、`find`(1) でコピー対象のファイル名を抽出して `cpio`(1)
でアーカイブ化、`cpio`(1) で展開するのがよいです。

例:

```

    $ (
        cd /path/to/src/dir && find . -type f -name '*.x' -print0 |cpio -o0
      ) \
      |(
        cd /path/to/dst/dir && cpio -id
      )
    
```
CC BY-SA 4.0
2019-07-14T14:25:46.277
56640
2019-07-15T06:25:09.803
2019-07-15T06:25:09.803
3061
3061
56585
answer
コメントで`rsyncのexcludeオプション、と書かれていますが、includeの書き間違いだと思います。ということで、rsyncにはコピーする対象をincludeオプションで絞り込むことができます。ただ、ディレクトリを再帰的にコピーする時には若干ややこしく、

```

    rsync -a --include='*/' --include='*.x' --exclude='*' src/ dst
    
```

こんな感じで指定する必要があります。

tarでxargs使うのもいいですが、`--files-from`オプションを使うと対象にするパスのリストをファイルで指定できます。

```

    cd source_dir/
    find . -name "*.x" | tar cf - --files-from - | tar xf - -C destnation_dir/
    
```

xargsを必要とするほど大量にファイルがあるなら、tarで直接リストを読ませた方が効率的だと思います。
CC BY-SA 4.0
2019-07-15T13:22:09.073
56662
2019-07-15T13:22:09.073
5793
56585
answer