Iterate over files containing string in file name and copy to directory, parse date from file

I'm trying to copy all files in a directory with a specific file name to a different directory. However, when I try to print the file name or copy the file over, the file name is printed as blank line / the file to be copied is considered blanks. The c parameter is passed in through the command line.

I know there are matches for the parameter, so why is it evaluated as blank?

Code:

#!/bin/bash
set -x
printf 'Processing option arguments:\n'
while getopts ":b:c:e:" arg; do case "${arg}" in b) b="$OPTARG"; echo "\$b is $b";; c) c="$OPTARG"; echo "\$c is $c";; e) e="$OPTARG"; echo "\$e is $e";; esac
done
printf 'Done.\n\n'
shift $((OPTIND - 1))
printf 'Remaining (non-option) arguments:\n'
printf '%s\n' "$@"
cd "/opt/data"
ssh MyHost << EOF
rm -rf testDirectory
mkdir testDirectory
find . -type f -name '*$c*' -print0 | while IFS= read -r -d $'\0' file;
do cp -r $file /testDirectory
done
EOF

Output:

cp: missing destination file operand after `/testDirectory'
Try `cp --help' for more information.

calling the script like this:

bash script.sh -b 06-30-20-18-10 -e 06-30-20-23-59 -c fileNameToMatch

Edit: I am trying to parse the file name:
Test_07_24_18_09_53.log

to be: 1807180953

the format of YearMonthDayHourMinute
How do I parse the date like this?
I am trying to use SED but it evaluates as blank: f=$(echo "$file" | sed 's/[a-zA-Z./]*//g')
>
month=$(echo "$f" | cut -d- -f1)

day=$(echo "$f" | cut -d- -f2)

year=$(echo "$f" | cut -d- -f3)

2

1 Answer

As mentioned in this comment, you have used the unquoted EOF in order to allow $c to be expanded to its value in the local shell before being passed to the remote shell via ssh. That also allows $file (and $'\0' - but that expands to the same thing in either shell) to be expanded locally - where it is presumably empty. Since you didn't double-quote it, the copy command becomes

cp -r /testDirectory

so /testDirectory becomes the cp command's SOURCE parameter, and its DEST is missing.

To prevent premature evaluation of $file you can backslash-escape the $. You should also double-quote the expansion:

find . -type f -name '*$c*' -print0 | while IFS= read -r -d $'\0' file;
do cp -r "\$file" /testDirectory
done

You could also backslash-escape $'\0' or simply replace it with the empty string '' which works as well for null-delimited data.

However it would be more efficient to avoid the remote shell loop altogether, using GNU cp's -t DIRECTORY SOURCE format:

find . -type f -name '*$c*' -exec cp -t /testDirectory {} + 
2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like