Skip to content

Instantly share code, notes, and snippets.

@agerwick
Last active December 18, 2015 16:29
Show Gist options
  • Save agerwick/5811577 to your computer and use it in GitHub Desktop.
Save agerwick/5811577 to your computer and use it in GitHub Desktop.
Bash script for copying all files in a directory tree matching one or more specified patterns (such as *.txt) to another tree, creating any directories not already existing. Copies only the path below the source directory to the destination.
#!/bin/bash
# copy-files-matching-pattern-preserving-path
# Bash script for copying all files in a directory tree matching one or more specified patterns (such as *.txt) to another tree, creating any directories not already existing.
# Copies only the path below the source directory, and only creates directories with files matching the pattern.
# (c)2013 Ronny Ager-Wick, released under GPLv3
options=$1
if [[ "${options:0:1}" = "-" ]]; then
# first char is dash
if [[ "$options" = "-n" ]]; then
trial_run="1"
source_path=$2
raw_patterns=$3
destination_path=$4
if [[ "$5" != "" ]]; then too_many_params=1; fi
else
echo "Invalid option: $options"
echo
# by not setting destination_path, the syntax and examples will be displayed below this message
fi
else
source_path=$1
raw_patterns=$2
destination_path=$3
if [[ "$4" != "" ]]; then too_many_params=1; fi
fi
if [[ "$too_many_params" = "1" ]]; then
echo "Too many parameters - maybe you forgot to encose the filename pattern in quotes?"
echo "Your paramters were: $*"
echo
destination_path="" # displays the syntax and examples below
fi
if [[ "$destination_path" = "" ]]; then
echo "Syntax: $0 [-n] source_path \"filename_pattern\" destination_path"
echo "copies all files matching filename_pattern within source_path to destination_path, preserving pathname after source_path"
echo "filename_pattern must be enclosed in quotes to avoid shell expanding wildcards if a match is found in the current directory."
echo
echo "Options:"
echo "-n trial-run - show what will be done without doing it"
echo
echo "Examples:"
echo "$0 /var/lib/gems/1.9.2/gems \"*.so\" vendor"
echo "$0 /path/to/pictures/and/movies/ \"*.jpg *.jpeg *.png *.JPG *.JPEG *.PNG\" /path/to/where/I/want/pictures/only/"
exit 1
fi
# process filename pattern
i="first"
filename_pattern=""
for raw_pattern in "$raw_patterns"
do
if [[ "$i" != "first" ]]; then
filename_pattern="$filename_pattern -o"
fi
filename_pattern="$filename_pattern -name $raw_pattern"
i="not first"
done
filename_pattern="$filename_pattern "
if [[ "$trial_run" == "1" ]]; then
echo "Trial-run - no files will be copied."
echo -n "Would have copied "
else
echo -n "Copying "
fi
echo "$raw_patterns from $source_path to $destination_path..."
for f in `set -f; find $source_path $filename_pattern -type f -printf '%P '`
do
echo "${source_path%/}/$f ==> ${destination_path%/}/$f"
if [[ "$trial_run" != "1" ]]; then
mkdir -p `dirname "$destination_path/$f"`
cp "${source_path%/}/$f" "${destination_path%/}/$f"
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment