From 4cb20a50faf31eef9341d195694bb7f97e740878 Mon Sep 17 00:00:00 2001 From: Michael Campagnaro Date: Mon, 22 Nov 2021 11:13:23 -0500 Subject: [PATCH] Support file filtering when copying a directory --- script_helpers/file_ops.sh | 81 +++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/script_helpers/file_ops.sh b/script_helpers/file_ops.sh index e723ef8..5094560 100644 --- a/script_helpers/file_ops.sh +++ b/script_helpers/file_ops.sh @@ -49,7 +49,8 @@ unix_to_windows_path() { } # Returned value does not have a trailing '/'. -windows_to_unix_path() { +# Expects the provided path to be an absolute path (i.e. has been passed through expand_path). +absolute_windows_to_unix_path() { local ret="$1" ret="/${ret/:/}" # Remove drive ':'. ret="${ret//\\//}" # Replace Windows slashes. @@ -62,8 +63,10 @@ windows_to_unix_path() { } # Returns a Unix path without escaped spaces, e.g. "/x/some folder" instead of "/x/some\ folder" -windows_to_unix_path_unescaped() { - local ret=$(windows_to_unix_path "$1") +# Will work with a relative or absolute path. The returned path will be expanded. +windows_to_unix_path_unescaped_and_expanded() { + local expanded=$(expand_path "$1") + local ret=$(absolute_windows_to_unix_path "$expanded") ret="${ret/\\ / }" # Remove '\' that appears before spaces. echo "$ret" } @@ -179,7 +182,7 @@ path_has_a_space() { if [[ $1 =~ $regexp ]]; then echo 1; else echo 0; fi } -expand_path_if_not_symlink_or_absolute() { +expand_unix_path_if_not_symlink_or_absolute() { local path="$1" if [[ $(is_absolute_unix_path "$path") -eq 0 && $(is_any_part_of_path_a_symlink "$path") -eq 0 ]]; then path=$(expand_path "$path") @@ -187,69 +190,91 @@ expand_path_if_not_symlink_or_absolute() { echo $path } +# Moves a single file. Optionally provide a new file name as a third param. move_file() { local src="$1" local src_expanded=$(expand_path "$src") - local dest_path=$(windows_to_unix_path_unescaped "$2") - local dest_filename="$3" + local dest="$2" + local dest_expanded=$(windows_to_unix_path_unescaped_and_expanded "$dest") + local dest_filename="$3" if [[ $dest_filename == "" ]]; then dest_filename=$(strip_path "$src") fi if [[ -e "$src_expanded" ]]; then - mkdir -p "$dest_path" + mkdir -p "$dest_expanded" - local dest="$dest_path/$dest_filename" - mv "$src_expanded" "$dest" - printf "${BOLD}${GREEN}==> ${NORMAL}${BOLD}move: ${YELLOW}'$src'${NORMAL}${BOLD} to ${YELLOW}'$dest'${NORMAL}\n" 2>/dev/null + local move_dest="$dest_expanded/$dest_filename" + + mv "$src_expanded" "$move_dest" + printf "${BOLD}${GREEN}==> ${NORMAL}${BOLD}move: ${YELLOW}'$src'${NORMAL}${BOLD} to\n ${YELLOW}'$move_dest'${NORMAL}\n" 2>/dev/null else printf "${BOLD}${RED}==> move: ${YELLOW}'$src' ${RED}doesn't exists${NORMAL}\n" return fi } +# Copies a single file. Optionally provide a new file name as a third param. +# If you want to copy all files with a specific extension then use copy_dir_files. copy_file() { local src="$1" local src_expanded=$(expand_path "$src") - local dest_path=$(windows_to_unix_path_unescaped "$2") - local dest_filename="$3" + local dest="$2" + local dest_expanded=$(windows_to_unix_path_unescaped_and_expanded "$dest") + local dest_filename="$3" if [[ $dest_filename == "" ]]; then dest_filename=$(strip_path "$src_expanded") fi if [[ -e "$src_expanded" ]]; then - mkdir -p "$dest_path" + mkdir -p "$dest_expanded" - local dest="$dest_path/$dest_filename" - cp "$src_expanded" "$dest" - printf "${BOLD}${GREEN}==> ${NORMAL}${BOLD}copy: ${YELLOW}'$src'${NORMAL}${BOLD} to\n ${YELLOW}'$dest'${NORMAL}\n" 2>/dev/null + local copy_dest="$dest_expanded/$dest_filename" + + cp "$src_expanded" "$copy_dest" + printf "${BOLD}${GREEN}==> ${NORMAL}${BOLD}copy: ${YELLOW}'$src'${NORMAL}${BOLD} to\n ${YELLOW}'$copy_dest'${NORMAL}\n" 2>/dev/null else printf "${BOLD}${RED}==> copy: ${YELLOW}'$src' ${RED}doesn't exists${NORMAL}\n" return fi } -copy_dir_files() { +# Copies a directory. You can restrict which files are copied by passing a wildcard as a third param, e.g. "*.cs" +copy_dir() { local src="$1" local src_expanded=$(expand_path "$src") - local dest_path=$(windows_to_unix_path_unescaped "$2") + local dest="$2" + local dest_expanded=$(windows_to_unix_path_unescaped_and_expanded "$dest") + + local opt_name_filter="$3" if [[ -d $src_expanded ]]; then - mkdir -p $dest_path + if [[ $opt_name_filter != "" ]]; then + # Copy all files in source dir with given name filter. + src_dir_name=$(strip_path "$src_expanded") + copy_dest="$dest_expanded/$src_dir_name" + mkdir -p "$copy_dest" - # Need to escape in order to use the wildcard and we have to eval in order to retain the backslash. - local src_escaped=$(escape_unix_path "$src_expanded") - cmd="cp -r $src_escaped/* \"$dest_path\"" - eval $cmd - - printf "${BOLD}${GREEN}==> ${NORMAL}${BOLD}copy *: ${BOLD}${YELLOW}'$src/*'${NORMAL}${BOLD} into ${YELLOW}'$dest_path'${NORMAL}\n" 2>/dev/null + find "$src_expanded" -maxdepth 1 -type f -iname "$opt_name_filter" -print0 | + while IFS= read -r -d '' line; do + dest_filename=$(strip_path "$line") + cp "$line" "$copy_dest" + printf "${BOLD}${GREEN}==> ${NORMAL}${BOLD}copy: ${YELLOW}'$line'${NORMAL}${BOLD} to\n ${YELLOW}'$copy_dest/$dest_filename'${NORMAL}\n" 2>/dev/null + done + else + mkdir -p "$dest_expanded" + # Have to eval in order to retain the backslash. + cmd="cp -r $src_expanded \"$dest_expanded\"" + eval $cmd + printf "${BOLD}${GREEN}==> ${NORMAL}${BOLD}copy: ${YELLOW}'$src'${NORMAL}${BOLD} to\n ${YELLOW}'$dest_expanded'${NORMAL}\n" 2>/dev/null + fi else - printf "${BOLD}${RED}==> copy *: ${YELLOW}'$src' ${RED}doesn't exists${NORMAL}\n" + printf "${BOLD}${RED}==> copy: ${YELLOW}'$src' ${RED}doesn't exists${NORMAL}\n" return fi } @@ -302,7 +327,7 @@ make_link() { if [[ $expand_source_symlink -eq 1 ]]; then final_src=$(expand_path "$final_src") else - final_src=$(expand_path_if_not_symlink_or_absolute "$final_src") + final_src=$(expand_unix_path_if_not_symlink_or_absolute "$final_src") # Having issues with mingw symlinking a path in the cwd to a dest that's not in the cwd. # We prepend the cwd when it's not an absolute path in order to work around the issue. @@ -312,7 +337,7 @@ make_link() { fi fi fi - final_dest=$(expand_path_if_not_symlink_or_absolute "$final_dest") + final_dest=$(expand_unix_path_if_not_symlink_or_absolute "$final_dest") fi local source_has_space=$(path_has_a_space "$final_src")