Copy folder recursively, excluding some folders

2019-01-05 07:05发布

I am trying to write a simple bash script that will copy the entire contents of a folder including hidden files and folders into another folder, but I want to exclude certain specific folders. How could I achieve this?

7条回答
劫难
2楼-- · 2019-01-05 08:07

inspired by @SteveLazaridis's answer, which would fail, here is a POSIX shell function - just copy and paste into a file named cpx in yout $PATH and make it executible (chmod a+x cpr). [Source is now maintained in my 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 "$@"

Example usage

EXCLUDE="
.git
my_secret_stuff
"
cpr "$HOME/my_stuff" "/media/usb" "$EXCLUDE"
查看更多
登录 后发表回答