「cp」コマンドを使用して特定のディレクトリを除外する方法は?


411

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



6
tar -c | tar -x
mvds

1
@mvds、同意してください。「-exclude」を指定してtarを使用することをお勧めします。
Huang F. Lei

回答:


704

rsyncは高速で簡単です。

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

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

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

dirのことを注意thefoldertoexcludeした後--excludeオプションがに相対的であるsourcefolder、すなわち、sourcefolder/thefoldertoexclude

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


3
同意した、あなたはのシンプルさとパワーを打ち負かすことはできません--exclude
マシュー・ウィルコクソン

31
であるthefoldertoexcludeと比較しsourcefolderたり、現在の作業ディレクトリは?感謝
Beebee 2013

46
ソースフォルダーを基準にしています。これにより、source / .gitフォルダーがコピーから除外されます。rsync -r --exclude '.git' source target
orkoden

15
多分私は間違っているかもしれませんが、「パラメータ」の前に「スイッチ」を追加することは良い習慣だと思います。また、rsyncのmanページでは、 "="構文の使用の有無にかかわらず、使用不可を報告しています。したがって、オペレーティングシステム全体で標準化するために、私は使用しますrsync -av --progress --exclude="thefoldertoexclude" sourcefolder /destinationfolder-とにかく、検索の代わりにrsyncに賛成票を投じます。検索中にソースの絶対パスを簡単に使用できるため{}、dst でを使用するのでトリッキーです。
Xavi Montero、

1
@mamunもちろん、たとえばリモートサーバーからローカルマシンへ: $ rsync user@example.com:/var/www/mypage /var/www/mylocalpage/またはローカルからリモートへ$ rsync /var/www/mylocalpage/ user@example.com:/var/www/mypage
sobi3ch 2015年

84

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

バッシュ

man 1 bash/ extglob

例:

$ shopt -s extglob
$エコー画像/ *
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

man 1 zshexpn/ ファイル名生成

setopt KSH_GLOBbashのようなパターンを使用できます。または、

%setopt EXTENDED_GLOB
%エコー画像/ *
images / 004.bmp images / 033.jpg images / 1276338351183.jpg images / 2252.png
%エコー画像/*~*.jpg
images / 004.bmp images / 2252.png

したがって、x~yパターンxに一致しますが、パターンを除外しますy。繰り返しますが、詳細についてはマンページを参照してください。


新しい

魚のシェルが持つ非常にきれい答え、これには:

🐟cp(string match -v '* .excluded.names'-srcdir / *)destdir

ボーナスプロチップ

と入力cp *してヒットしCtrlX*、何が起こるかを確認します。それは私が約束するはありません


@MikhailGolubtsovおそらくそれは、グロビングが再帰的ではなく、一度に1つのレベルで機能するためです。編集しました。PS:それでも動作しzshます。
ulidtko 2015

3
素敵なプロチップ!この方法で、単一のアイテムを簡単に削除できます。どうもありがとう!
タフィット

ところで、Bashで拡張パターンマッチング機能をオフにするには、を実行しsetopt -u extglobます。
Rockallite

49

できるrsyncときに使用する理由:

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

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


8
-path-inameではなくパス階層をテストするための引数が必要だと思います
James Murty

3
そして、あなたはまた、最後にセミコロンが必要になります:find . -type f -not -path '*/not-from-here/*' -exec cp '{}' '/dest/{}' \;
マシューWilcoxson

1
うわー、「編集は6文字以上にする必要があります」!
マシューウィルコクソン2013

1
@MatthewWilcoxson Meh。これらの制限は、担当者がもう少し増えるとすぐに解除されます。私はそれに応じて答えを編集しました。再度、感謝します!
Linus Kleen 2013

1
@ヘニングどうしてrsync?システムに存在しない可能性があります!ながらfindcp常に自分の場所にいます。それとも、単純なことをするために2ギグのものをインストールしたような人からですか?
Reishin

37
cp -r `ls -A | grep -v "c"` $HOME/

1
Windows 10 .shで私のために働いた
atwellpub '6/07/17

:カスタムソースパスとひとつのファイルまたはディレクトリの除外のための使用を簡素化するシェル関数メイド # $1 = source path # $2 = destination path # $3 = filter copy_from_source_to_destination_except_filter() { cp -r $(ls -A $1 | grep -v -w $3 | awk -v path=$1 '{printf "%s/%s ", path, $1}') $2 }
ElectRocnic

スペースを含むディレクトリで失敗
セルジオ

27

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

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

9
うまくいきません。私が得る-bash: !: event not found
ジェネラマ

8
shopt -s extglob(これを実行して、cp、rmなどで!を有効にします)
imkost



8

rsync

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

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


トップアンサーとの違い/改善点は何ですか?
アクティビティを削減

7

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

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

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


9
あなたは余分lsをスキップし、単に行うことができますcp !(file1|file1) dest
Shawn Chin

-laRは使用しないでください。cpを妨害する文字列を追加します。 cp $(ls folder/!exclude_folder0|exclude_folder1)) dest
LAL

5

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


4

rsync実際にはかなりトリッキーです。機能させるには、複数のテストを実行する必要があります。

コピー/var/www/htmlしたい/var/www/devが、おそらくサイズが原因でディレクトリを除外する 必要があるとしましょう/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あり、アーカイブモード用です。つまり、再帰が必要で、ほとんどすべてを保持したいということです。


特殊文字や空白の心配を取るシンプルなソリューション
セルジオ

現在の上位の回答とは異なり、パラメーターを説明していただきありがとうございます。
アクティビティを削減

3
cp -rv `ls -A | grep -vE "dirToExclude|targetDir"` targetDir

編集:ターゲットパスも除外するのを忘れました(そうしないと、再帰的にコピーされます)。


4
スペースを含むディレクトリエントリに注意してください。
Paulo Scardine、2011年

3

これは、Linus Kleenの回答を変更したものです。彼の答えは私のためにうまくいきませんでした。cpが好まないファイルパスの前に追加されました(パスはsource / .destination / fileのようになります)。

このコマンドは私のために働きました:

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

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


2

一時的に隠しディレクトリに移動するだけです(必要に応じて、後で名前を変更します)。

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

1
おそらくそうではないかもしれませんが、これは私がここで見つけた唯一のオプションでcpあり、のような標準のPOSIXシェルで動作しshます。
tomekwi

1
この答えは劇的に過小評価されています。これは、最も互換性があり、最も読みやすく、理解しやすい回答です。どうも、どうして考えなかったのかわからない。
Robert Talada

@RobertTaladaに感謝します。答えは今からどこまで行きますか。️‍🌈
lama12345


0

「do while」ループを使用して、findコマンドの出力を読み取ります。この例では、特定のパターンを(除外するのではなく)一致させています。これは、不要なパターン一致よりも必要なパターン一致の数が限られているためです。-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 Live Hub上のファイルよりもサーバー上で新しいすべての音楽タイプファイルをコピーします。上記を使用しているのは、除外したいDVDファイルやmpegなどがたくさんあり、かつ、何らかの理由で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/

0
ls -I "filename1" -I "filename2" | xargs cp -rf -t destdir 

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


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.