フォルダー構造を維持したまま特定のファイルタイプをコピーする


108

フォルダー構造があり、*。csvファイルがフォルダー全体に散らばっています。ここで、フォルダー構造を維持したまま、すべての* .csvファイルを別の宛先にコピーします。

それは次のように動作します:

cp --parents *.csv /target
cp --parents */*.csv" /target
cp --parents */*/*.csv /target
cp --parents */*/*/*.csv /target
...

などなど、しかし、私は1つのコマンドを使用してそれをやりたいです。

回答:


126

人々がfindの使用に抵抗する理由はあります-execか?とても便利です。

find . -name '*.csv' -exec cp --parents \{\} /target \;

ツールを知ってください。;-)


62
おそらくこの\ {\} \;が原因です。
igo

12
'{}'同じようにうまく機能
OrangeDog

3
にもかかわらず-execdirよりも安全である-execことを目的として、単に他との1を交換すると、フォルダ構造を維持しません。
サイモンシャイン

2
コマンドでそれらをコピーしようとすると、「ディレクトリを省略しています」というメッセージが表示されます。
ヴィッキー開発

4
ここでブレースをエスケープする必要がある理由を説明できますか?
ヌメノン

46

rsyncこれにも使用できます。

$ rsync -a --prune-empty-dirs --include '*/' --include '*.csv' --exclude '*' source/ target/

ソースツリーから空のディレクトリを保持する場合は、--prune-empty-dirsオプションをスキップします。

$ rsync -a --include '*/' --include '*.csv' --exclude '*' source/ target/

シンボリックリンク、変更日、ファイル許可、所有者などを保持したくない場合は、の-a別の組み合わせに置き換えてください-rlptgoD。;-)


1
-mはのショートカットです--prune-emty-dirs
ジェレミア

また、-Rソースの親ディレクトリ構造をコピーするオプションを追加できます。(ここでの私の答えを参照。)
ジェレミア

-Rは私のために働く!ありがとう
gigi2

32

パススルーモードでfindおよびcpioを使用できます。

find . -name '*.csv' | cpio -pdm  /target

これにより、現在のディレクトリ以下にあるすべての.csvファイルが検索され、/ targetにコピーされ.ます。

使用する場合

find /path/to/files -name '*.csv' | cpio -pdm /target

/path/to/files以下のすべてのファイルが検索され、以下にコピーされ/target/path/to/filesます。


3
すべての回答をこの質問にトップダウンで試しましたが、これが最初の試みで働いた唯一の
回答でした-OscarRyz

21

このcpコマンドは、複数のソース引数を許可します。

cp **/*.csv --parents ../target

警告:ここでは再帰的なglobを使用しています。これは、globstarBash 4+およびのオプションでありksh、デフォルトではでサポートされていますzsh。再帰的なグロブ隠しファイルやフォルダーと一致せず一部の実装はシンボリックリンクをたどりますが、そうでないものもあります。

シェルが再帰的なグロブをサポートしていない場合、またはそれらを使用しない場合は、次の操作を実行できます。

  • *.csv */*.csv */*/*.csv */*/*/*.csv -これはもちろん非常に冗長であり、ディレクトリ構造の深さを知る必要があります。
  • $(find . -name '*.csv')-これ隠しファイルとフォルダーに一致します。findまた、シンボリックリンクをたどるかどうかの指定もサポートしています。

これはまさに私が試したもの(再帰的なグロブ)であり、すべてではなくいくつかを見つけましたか?かなり奇妙です。npm copyfilesスクリプトを使用しても同じ結果が得られましたが、findコマンドを使用するとすべてが検出されます
...-Randyaa

@Randyaaあなたを助けるために、正確にはどのファイルが見つからなかったかについて、もう少し詳細が必要です。あなたは議論を見つけることができ、ここで、継続的ここに便利な再帰グロブの正確な行動について。
カイルストランド

1
再帰的なグロブが何らかの理由で有効になっていないことが判明しました...私はこれに遭遇したことはありませんがshopt -s globstar、コマンドの直前に実行するだけで修正し、すべてが順調です。フォローアップしてくれてありがとう!
ランディア

--parents私が探していたものでした。おかげで
ジョシュ

17

これは私のために働いた:

find -name "*.csv" | xargs cp --parents -t /target


最も単純な構文でのベストアンサー。うまく機能し、覚えやすいです。多くの場合find [things] | xargs [do stuff]、非常に強力です。
毎日宇宙飛行士

同意した。他の回答のいくつかと比較して非常に簡単です。
ティムB

1
あなたは、ファイル名にスペースがあればブレイク
ミシェルPiccolini

ファイル名の@MichelePiccoliniスペースは、find -print0およびで処理できますxargs -0
pasztorpisti

8

この構造をから./sourceに複製すると仮定します./destination

cd source
find . -name "*.csv" | xargs tar cvf - | (cd ../destination ; tar xfp -)

私はそれを1行として数える用意ができていますcd source。これはシェルの組み込みです。


2
私は彼が本当に1つのコマンドを意味するとは思わない-彼の例のように

tar-C最初にディレクトリを変更する必要を回避するオプションがあります。
バート

8

rsyncのマンページから:

-R、-相対的

相対パスを使用します。これは、ファイル名の最後の部分ではなく、コマンドラインで指定されたフルパス名がサーバーに送信されることを意味します。これは、複数の異なるディレクトリを同時に送信する場合に特に便利です。たとえば、次のコマンドを使用した場合:

rsync -av /foo/bar/baz.c remote:/tmp/

...これにより、リモートマシンの/ tmp /にbaz.cという名前のファイルが作成されます。代わりに使用した場合

rsync -avR /foo/bar/baz.c remote:/tmp/

次に、/ tmp / foo / bar / baz.cという名前のファイルがリモートマシン上に作成され、そのフルパスが保持されます。これらの追加のパス要素は、「暗黙のディレクトリ」と呼ばれます(つまり、上記の例の「foo」および「foo / bar」ディレクトリ)。

したがって、これも機能します:

rsync -armR --include="*/" --include="*.csv" --exclude="*" /full/path/to/source/file(s) destination/
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.