Reputation: 211
I have the following script to recursively clean up directories when they no longer contain (any directories with) any .mp3 or .ogg files:
set -u
find -L $1 -depth -type d | while read dir
do
songList=`find -L "$dir" -type f \( -iname '*.ogg' -o -iname '*.mp3' \)` && {
if [[ -z "$songList" ]]
then
echo removing "$dir"
rm -rf "$dir"
fi
}
done
This works great, except that it fails in the case of directories that have a space as the last character of their name, in which case the second find
fails, with the following feedback, if the script is invoked with . as its only argument, and a directory with the path './FOO/BAR BAZ '
(note the space at the end) exists:
find: `./FOO/BAR BAZ': No such file or directory
(Note the space that is now missing at the end, though other spaces are left intact.)
I'm pretty sure it's a quoting thing, but every other way of quoting I've tried makes the behavior worse (i.e. more directories failing).
Upvotes: 0
Views: 65
Reputation: 123448
read
is splitting the input when it encounters spaces. Quoting help read
:
Read a line from the standard input and split it into fields.
Reads a single line from the standard input, or from file descriptor FD
if the -u option is supplied. The line is split into fields as with word
splitting, and the first word is assigned to the first NAME, the second
word to the second NAME, and so on, with any leftover words assigned to
the last NAME. Only the characters found in $IFS are recognized as word
delimiters.
You could set IFS
and avoid the word splitting. Say:
find -L "$1" -depth -type d | while IFS='' read dir
Upvotes: 5