숨겨진 파일과 폴더를 포함한 폴더의 전체 내용을 다른 폴더에 복사하는 간단한 bash 스크립트를 작성하려고하지만 특정 폴더를 제외하고 싶습니다. 어떻게하면 되나요?
cp -R !(dir1|dir2) path/to/destination
!(dir1|dir2)
패턴이 필요 extglob
켜야하는 ( shopt -s extglob
을 켭니다).
숨겨진 파일과 폴더를 포함한 폴더의 전체 내용을 다른 폴더에 복사하는 간단한 bash 스크립트를 작성하려고하지만 특정 폴더를 제외하고 싶습니다. 어떻게하면 되나요?
cp -R !(dir1|dir2) path/to/destination
!(dir1|dir2)
패턴이 필요 extglob
켜야하는 ( shopt -s extglob
을 켭니다).
답변:
rsync를 사용하십시오.
rsync -av --exclude='path1/to/exclude' --exclude='path2/to/exclude' source destination
사용합니다 source
과 source/
다르다. 후행 폴더의 내용을 복사하는 수단 슬래시 source
로를 destination
. 슬래시가 없으면 폴더 source
를에 복사하는 것을 의미합니다 destination
.
또는 제외 할 디렉토리 (또는 파일)가 많은 경우를 사용할 수 있습니다 --exclude-from=FILE
. 여기서 제외 할 FILE
파일 또는 디렉토리를 포함하는 파일 이름입니다.
--exclude
와 같은 와일드 카드를 포함 할 수도 있습니다. --exclude=*/.svn*
rsync -av --exclude='.git/' ../old-repo/ .
파이프와 함께 타르를 사용하십시오.
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보다 더 밀접하게 바인딩됩니다. 어쨌든 기본값이지만 괄호는 무슨 일이 일어나고 있는지 보여줍니다. 의 위에.
Jeff의 아이디어와 비슷합니다 (예상치 않음).
find . -name * -print0 | grep -v "exclude" | xargs -0 -I {} cp -a {} destination/
/usr/share/icons
즉시 얻었습니다 find: paths must precede expression: 22x22
. . 내 명령은 find . -name * -print0 | grep -v "scalable" | xargs -0 -I {} cp -a {} /z/test/
(실제로 MSYS2에 /mingw64/share/icons/Adwaita
있지만 실제로 는 MSYS2의 결함인지 알 수 없음)
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"