web-dev-qa-db-ja.com

一部のフォルダーを除外して、フォルダーを再帰的にコピーします

隠しファイルやフォルダーを含むフォルダーの内容全体を別のフォルダーにコピーする単純なbashスクリプトを作成しようとしていますが、特定の特定のフォルダーを除外したいです。どうすればこれを達成できますか?

187
trobrock

Rsyncを使用します。

rsync -av --exclude='path1/to/exclude' --exclude='path2/to/exclude' source destination

sourcesource/の使用は異なることに注意してください。末尾のスラッシュは、フォルダーsourceの内容をdestinationにコピーすることを意味します。末尾のスラッシュがない場合、フォルダーsourcedestinationにコピーすることを意味します。

あるいは、除外するディレクトリ(またはファイル)が多数ある場合は、--exclude-from=FILEを使用できます。ここで、FILEは、除外するファイルまたはディレクトリを含むファイルの名前です。

--excludeには、--exclude=*/.svn*などのワイルドカードを含めることもできます

314
Kaleb Pederson

パイプと一緒にタールを使用します。

cd /source_directory
tar cf - --exclude=dir_to_exclude . | (cd /destination && tar xvf - )

Ssh全体でこの手法を使用することもできます。

37
Kyle Butt

find-Pruneオプションとともに使用できます。

man findの例:

 cd /source-dir
 find。 -name .snapshot -Prune -o \(\!-name *〜-print0 \)| 
 cpio -pmd0 /dest-dir

このコマンドは/の内容をコピーしますsource-dirから/ dest-dir。ただし、.snapshotという名前の
ファイルとディレクトリ(およびその中のすべて)は省略します。また、
テントではなく、名前が〜で終わるファイルまたはディレクトリを省略します。コンストラクト-Prune -o \(... -print0 \)は非常に一般的です。ここでの
の考え方は、-Pruneの前の表現が、
がプルーニングされるものに一致するということです。ただし、-Pruneアクション自体はtrueを返すため、-oの後の
は、
の枝刈りされなかったディレクトリ(枝刈りされた
ディレクトリはアクセスされないため、その内容は無関係です。
 -oの右側の表現は、わかりやすくするために括弧のみ
で示しています。 -Pruneが適用されていないものに対してのみ-print0アクションが実行されることを強調します。テスト間の
デフォルトの「and」条件は-oよりも強くバインドするため、これはデフォルトです。しかし、括弧は何が起こっているかを示すのに役立ちます。
 .. ____。]
9

--excludeオプションを指定してtarを使用し、宛先でtarを展開できます。例えば

cd /source_directory
tar cvf test.tar --exclude=dir_to_exclude *
mv test.tar /destination 
cd /destination  
tar xvf test.tar

詳細については、tarのmanページを参照してください

3
ghostdog74

ジェフのアイデアに似ています(未検証):

find . -name * -print0 | grep -v "exclude" | xargs -0 -I {} cp -a {} destination/
2
EXCLUDE="foo bar blah jah"                                                                             
DEST=$1

for i in *
do
    for x in $EXCLUDE
    do  
        if [ $x != $i ]; then
            cp -a $i $DEST
        fi  
    done
done

未テスト...

0
Steve Lazaridis

失敗する@SteveLazaridisの答えに触発され、ここにPOSIXシェル関数があります-yout $PATHcpxという名前のファイルにコピーして貼り付け、実行可能にします(chmod a+x cpr)。 [ソースは現在、私の GitLab で管理されています。

#!/bin/sh

# usage: cpx [-n|--dry-run] "from_path" "to_path" "newline_separated_exclude_list"
# limitations: only excludes from "from_path", not it's subdirectories

cpx() {
# run in subshell to avoid collisions
  (_CopyWithExclude "$@")
}

_CopyWithExclude() {
  case "$1" in
    -n|--dry-run) { DryRun='echo'; shift; } ;;
  esac

  from="$1"
  to="$2"
  exclude="$3"

  $DryRun mkdir -p "$to"

  if [ -z "$exclude" ]; then
      cp "$from" "$to"
      return
  fi

  ls -A1 "$from" \
    | while IFS= read -r f; do
        unset excluded
        if [ -n "$exclude" ]; then
          for x in $(printf "$exclude"); do
          if [ "$f" = "$x" ]; then
              excluded=1
              break
          fi
          done
        fi
        f="${f#$from/}"
        if [ -z "$excluded" ]; then
          $DryRun cp -R "$f" "$to"
        else
          [ -n "$DryRun" ] && echo "skip '$f'"
        fi
      done
}

# Do not execute if being sourced
[ "${0#*cpx}" != "$0" ] && cpx "$@"

使用例

EXCLUDE="
.git
my_secret_stuff
"
cpr "$HOME/my_stuff" "/media/usb" "$EXCLUDE"
0
go2null