web-dev-qa-db-ja.com

特定のディレクトリを除するための 'cp'コマンドの使い方

特定のサブディレクトリ内の一部のファイルを除いて、ディレクトリ内のすべてのファイルをコピーします。 'cp'コマンドに--excludeオプションがないことに気付きました。それで、どうすればこれを達成できますか?

341
David Liu

rsyncは速くて簡単です:

rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude

--excludeを複数回使用できます。

rsync -av --progress sourcefolder /destinationfolder --exclude thefoldertoexclude --exclude anotherfoldertoexclude

--excludeオプションの後のdir thefoldertoexcludeは、sourcefolderからの相対パス、つまりsourcefolder/thefoldertoexcludeであることに注意してください。

また、実際の操作を実行する前に何がコピーされるかを確認するためにドライラン用に-nを追加することもできます。すべて問題なければ、コマンドラインから-nを削除します。

575
hank

まあ、すべてのunix風のファイルユーティリティ(cp、mv、rm、tar、rsync、scpなど)で特定のファイル名パターンの除外を実行しなければならない場合、膨大な作業の重複が発生します。代わりに、そのようなことを globbing の一部として、つまりあなたのシェルによって行うことができます。

bash

Link をマニュアルにするには、extglobを検索してください。

例:

 $ shopt -s extglob 
 $ echo images /* 
 images/004.bmp images/033.jpg images/1276338351183.jpg images/2252.png 
 $ echo images /!(*。jpg)
 images/004.bmp images/2252.png 

だからあなたは!()の中にパターンを入れるだけで、それはマッチを無効にします。 (Vanwarilが別の答えで示すように)個々のパスの列挙から始めて、パターンは任意に複雑になることがあります:!(filename1|path2|etc3)、星や文字クラスを持つ正規表現のようなもの。詳細はマンページを参照してください。

zsh

リンク マニュアルへ、セクション "ファイル名生成"

setopt KSH_GLOBを実行してbash風のパターンを使用することができます。または、

%setopt EXTENDED_GLOB 
%echo images /* 
 images/004.bmp images/033.jpg images/1276338351183.jpg images/2252.png 
%echo images/*〜* .jpg 
 images/004.bmp images/2252.png 

そのため、x~yはpatternxと一致しますが、patternyは除外します。もう一度、完全な詳細についてはマンページを参照してください。


新しい!

fish Shellはこれに対して もっときれいな答え を持っています。

 ???? cp(文字列の一致-v '* .excluded.names'  -  srcdir/*)destdir 

ボーナスプロチップ

cp *と打ってヒット CtrlX* そして何が起こるか見てください。 有害ではない 約束します

74
ulidtko

あなたができるときrsyncを使う理由:

find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'

これは、ターゲットディレクトリ構造がソースのディレクトリ構造と同じであることを前提としています。

42
Linus Kleen
cp -r `ls -A | grep -v "c"` $HOME/
30
vineet kumar

私が見つけた最も簡単な方法は、ファイルとフォルダーを除くすべてのファイルを、括弧内に名前を追加するだけでコピーできることです。

shopt -s extglob
cp -r !(Filename1 | FoldernameX | Filename2) Dest/
21
securecurve

mvdsのコメント に展開して、これは私のために働きます

cd dotfiles
tar -c --exclude .git --exclude README . | tar -x -C ~/dotfiles2
10
Steven Penny

私はあなたがbashかダッシュを使っていると思います。これでうまくいくでしょうか。

shopt -s extglob  # sets extended pattern matching options in the bash Shell
cp $(ls -laR !(subdir/file1|file2|subdir2/file3)) destination

不要なファイルを除外してlsを実行し、それをcpの最初の引数として使用する

7
Vanwaril

rsync

rsync -r --verbose --exclude 'exclude_pattern' ./* /to/where/

最初に-nオプションを付けて試して、何がコピーされるのかを確認します。

7
dzon

ソースディレクトリからの相対パスです。
これはディレクトリsource/.gitをコピーから除外します。

rsync -r --exclude '.git' source target
7

もう1つのより簡単なオプションは--exclude-dirオプションを持つrsyncをインストールして使用することで、ローカルとリモートの両方のファイルに使用できます。

6
ehudokai

これはLinus Kleenの答えを修正したものです。あるだろうから彼の答えは私にはうまくいかなかった。 cpが気に入らないファイルパスの前に追加されます(パスはsource/.destination/fileのようになります)。

このコマンドは私にとって役に立ちました:

find . -type f -not -path '*/exlude-path/*' -exec cp --parents '{}' '/destination/' \;

--parentsコマンドはディレクトリ構造を保持します。

3
Milan Simek
mv tobecopied/tobeexcluded .
cp -r tobecopied dest/
mv tobeexcluded tobecopied/
2
John Smith

一時的に隠しディレクトリに一時的に移動してください(そして必要に応じて名前を変更してください)。

mkdir .hiddendir
cp * .hiddendir -R
mv .hiddendir realdirname
2
lama12345

Findコマンドの出力を読むために "do while"ループを使います。この例では、私が必要としているのとは限らない数のパターン一致があるので、(除外するのではなく)一致させています。 -inameフラグの前に-notを付けて論理を逆にすることができます。

    find . -type f -iname "*.flac" -o -print0 -iname "*.mp3" -print0 -o -iname "*.wav" -print0 -o -iname "*.aac" -print0 -o -iname "*.wma" -print0 | while read -d $'\0' file; do cp -ruv "$file" "/media/wd/network_sync/music/$file"; done

上記を使って、/ media/wdにマウントしたWestern Digital TVライブハブのファイルよりもサーバー上の新しい音楽タイプファイルをすべてコピーします。私は除外したいDVDファイル、mpegsなどがたくさんあるので、上記を使用します。そして、何らかの理由でrsyncがコピーしているように見えるのですが、wdデバイスを見た後、ファイルがないにもかかわらずこのコマンドでrsync中にエラー:

    rsync -av --progress --exclude=*.VOB --exclude=*.avi --exclude=*.mkv --exclude=*.ts --exclude=*.mpg --exclude=*.iso --exclude=*ar --exclude=*.vob --exclude=*.BUP --exclude=*.cdi --exclude=*.ISO --exclude=*.shn --exclude=*.MPG --exclude=*.AVI --exclude=*.DAT --exclude=*.img --exclude=*.nrg --exclude=*.cdr --exclude=*.bin --exclude=*.MOV --exclude=*.goutputs* --exclude=*.flv --exclude=*.mov --exclude=*.m2ts --exclude=*.cdg --exclude=*.IFO --exclude=*.asf --exclude=*.ite /media/2TB\ Data/data/music/* /media/wd/network_sync/music/
1
user3610268

rsyncは実際にはかなりトリッキーです。それを機能させるために複数のテストをしなければなりません。

/var/www/html/var/www/devにコピーしたいが、exclude/var/www/html/site/video/ディレクトリが必要であるとしましょう。コマンドは次のようになります。

rsync -av --exclude 'sites/video' /var/www/html/ /var/www/dev

一部の 警告

  1. ソースの最後のスラッシュ/は必要です。そうでなければ、その内容ではなくソースディレクトリもコピーして/var/www/dev/html/xxxxになります。
  2. --excludeパスは、直接ソースへの相対です。絶対パスでいってもうまくいきません。

  3. -vは冗長用、-aはアーカイブモード用です。つまり、 recursion が必要で、ほとんどすべてを保持したいということです。

1
Leon li

1つの方法は、find -0-Pruneを使用して移動するすべてのファイルとディレクトリを検索し、次にxargs -0を使用してそれぞれをコピーすることです。

1
Jason Orendorff
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir

編集:ターゲットパスも除外するのを忘れていました(そうでなければそれは再帰的にコピーするでしょう)。

1
sudo work
ls -I "filename1" -I "filename2" | xargs cp -rf -t destdir 

最初の部分lsは、-Iフラグが設定された特定のファイルを除くすべてのファイルです。 lsの出力は、2番目の部分の標準入力として使用されます。 xargs標準入力からコマンドcp -rf -t destdirをビルドおよび実行します。フラグ-rはディレクトリを再帰的にコピーすることを意味し、-fdestdir内のファイルを上書きするファイルを強制的にコピーすることを意味し、-tはコピー先ディレクトリを指定します。

0
LouisXW