[bash] 일부 폴더를 제외하고 폴더를 재귀 적으로 복사

숨겨진 파일과 폴더를 포함한 폴더의 전체 내용을 다른 폴더에 복사하는 간단한 bash 스크립트를 작성하려고하지만 특정 폴더를 제외하고 싶습니다. 어떻게하면 되나요?



답변

rsync를 사용하십시오.

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

사용합니다 sourcesource/다르다. 후행 폴더의 내용을 복사하는 수단 슬래시 source로를 destination. 슬래시가 없으면 폴더 source를에 복사하는 것을 의미합니다 destination.

또는 제외 할 디렉토리 (또는 파일)가 많은 경우를 사용할 수 있습니다 --exclude-from=FILE. 여기서 제외 할 FILE파일 또는 디렉토리를 포함하는 파일 이름입니다.

--exclude 와 같은 와일드 카드를 포함 할 수도 있습니다. --exclude=*/.svn*


답변

파이프와 함께 타르를 사용하십시오.

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

ssh에서이 기술을 사용할 수도 있습니다.


답변

옵션 find과 함께 사용할 수 있습니다 -prune.

예를 들면 다음과 man find같습니다.

       cd / source-dir
       찾기 . -name .snapshot -prune -o \ (\! -name * ~ -print0 \) |
       cpio -pmd0 / dest-dir

       이 명령은 / source-dir의 내용을 / dest-dir에 복사하지만 생략합니다.
       이름이 .snapshot 인 파일 및 디렉토리 또한
       ~로 끝나는 파일이나 디렉토리는 생략하지만 그 이름은 ~
       텐트. -prune -o \ (... -print0 \) 구문은 매우 일반적입니다. 그만큼
       여기서 아이디어는 정리 전의 표현은
       가지 치기. 그러나 -prune 조치 자체는 true를 리턴하므로
       다음 -o는 오른쪽이 다음에 대해서만 평가되도록합니다.
       정리되지 않은 디렉토리 (제거 된 내용)
       디렉토리도 방문하지 않으므로 내용은 관련이 없습니다).
       -o의 오른쪽에있는 표현식은 괄호 안에 있습니다.
       명확성을 위해. -print0 조치 만 발생 함을 강조합니다.
       자두가 적용되지 않은 것들에 대해. 때문에
       테스트 사이의 기본`and '조건은 -o보다 더 밀접하게 바인딩됩니다.
       어쨌든 기본값이지만 괄호는 무슨 일이 일어나고 있는지 보여줍니다.
       의 위에.


답변

–exclude 옵션과 함께 tar를 사용한 다음 대상에서 untar 할 수 있습니다. 예 :

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

자세한 내용은 tar 매뉴얼 페이지를 참조하십시오


답변

Jeff의 아이디어와 비슷합니다 (예상치 않음).

find . -name * -print0 | grep -v "exclude" | xargs -0 -I {} cp -a {} destination/


답변

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

테스트되지 않은 …


답변

실패 SteveLazaridis의 대답은, @ 영감, 여기 POSIX 쉘 기능입니다 – 그냥 복사 및 붙여 넣기라는 이름의 파일로 cpx행해져 Yout에 $PATH하고 executible 수 있도록 ( 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"