With:
Find="$(find / -name "*.txt" )"
du -hc "$Find" | tail -n1
echo "$Find" | xargs rm -r
If the file foo bar.txt
is found, it won't count it with du or remove the file. What would be the best way to escape the spaces?
Perhaps find / -name '*.txt' -exec du -hc {} \;
is more like what you're looking for?
But, doing it as you did, you're missing quotes in your call to du
, and needlessly using xargs
when it won't work… You seem enamoured of echo
, who is not your friend.
Since \0
isn't allowed in filenames, you can safely collect results from find
using its -print0
option:
date > /private/var/mobile/Documents/Local\ Cookies/Clean
find . -print0 | while IFS='' read -r -d '' file
do
du -hc "$file" | tail -n 1
rm "$file"
done
Corrected should work on MacOS and Linux now.
If none of your filenames can have embedded newlines (which would be very unusual), you can use the following:
Note: To prevent accidental deletion of files while experimenting with the commands, I've replaced
/
as the input dir. (as used in the question) with/foo
.Note that if you didn't need to collect all filenames ahead of time and don't mind running
find
twice, you can use a singlefind
command for each task (except for piping totail
), which is also the most robust option (the only caveat is that if you have so many files that they don't fit on a single command line,du
could be invoked multiple times).Using
+
to terminate the command passed to-exec
is crucial, as it instructsfind
to pass as many matches as will fit on a single command line to the target command; typically, but not necessarily, this results in a single invocation; effectively-exec ... +
is like a built-inxargs
, except that embedded whitespace in arguments is not a concern.In other words:
-exec ... +
is not only more robust than piping toxargs
, but - due to not needing a pipeline and another utility - also more efficient.