Issue
Doing a simple read in bash with this:
contents of list.txt:
/foo/bar/mydirectory/myfile.jpg
/foo/bar/mydirectory/deletedfile.jpg
/foo/bar/pictures\ of\ coffee\ cups/coffee-cup-42.jpg
#!/bin/bash
file="/foo/bar/list.txt"
while read -r line; do
echo "VALUE OF LINE VARIABLE IS: $line"
echo "COMMAND LINE IS: find -f $line"
find -f $line
# either file found, or "no such file" error
done <$file
Output of script:
dumbjoe$ ./read-test.sh
VALUE OF LINE VARIABLE IS: /foo/bar/mydirectory/myfile.jpg
COMMAND LINE IS: find -f /foo/bar/mydirectory/myfile.jpg
/foo/bar/mydirectory/myfile.jpg file is found
VALUE OF LINE VARIABLE IS: /foo/bar/mydirectory/deletedfile.jpg
COMMAND LINE IS: find -f /foo/bar/mydirectory/deletedfile.jpg
find: /foo/bar/mydirectory/deletedfile.jpg: No such file or directory file not found
VALUE OF LINE VARIABLE IS: /foo/bar/pictures\ of\ coffee\ cups/coffee-cup-42.jpg
COMMAND LINE IS: find -f /foo/bar/pictures\ of\ coffee\ cups/coffee-cup-42.jpg
find: /foo/bar/pictures\: No such file or directory
find: of\: No such file or directory
find: coffee\: No such file or directory
find: cups/coffee-cup-42.jpg: No such file or directory WHAT???
running the command in Terminal
dumbjoe$ find -f /foo/bar/pictures\ of\ coffee\ cups/coffee-cup-42.jpg
/foo/bar/pictures\ of\ coffee\ cups/coffee-cup-42.jpg file found
Why is this not working in the script??
EDIT: Ultimeately what I'm after is below, where I'm getting lost is the variable "multi-escaping":
file=$LISTOFFILES
while IFS= read -r line
do
let "FILESTESTED+=1"
FOUND="$(find -f $line)"
# if file is not found, ignore the error
exec 2> /dev/null
# if file is found:
if [ "$FOUND" == "$line" ]
then
echo "FOUND: $line" >> $REPORT
FILESIZE="$(find $line -exec ls -l {} \; | awk '{ print $5 }')"
echo "SIZE is: $FILESIZE" >> $REPORT
echo "-----------------------------------" >> $REPORT
let "SPACETOTAL= SPACETOTAL + FILESIZE"
let "FILES_FOUND_COUNT+=1"
fi
done <$file
All of this works IF there are no spaces present in the path.
Solution
You don't need to escape the spaces in the input file, because the shell won't process them. Just quote the parameter expansion.
Put the following in list.txt
:
/foo/bar/mydirectory/myfile.jpg
/foo/bar/mydirectory/deletedfile.jpg
/foo/bar/pictures of coffee/coffee-cup-42.jpg
Then change your script to
#!/bin/bash
file="/foo/bar/list.txt"
while IFS= read -r line; do
echo "VALUE OF LINE VARIABLE IS: $line"
echo "COMMAND LINE IS: find -f $line"
find -f "$line"
# either file found, or "no such file" error
done < "$file"
Answered By - chepner Answer Checked By - Katrina (WPSolving Volunteer)