Reputation: 1009
I'm trying to run a program on every file on a dir. But there is spaces in the name of the file. For example, a file can be named «/my/good/path/MY - AWFUL, FILE.DOC» And when I'm trying to send the path to my the other tool (a python script), I've got an error saying «MY» is not a existing file. :(
Here is my current bash code:
#!/usr/bin/bash
for file in $(find "/my/pash" -name "*.DOC")
do
newvar=`program "$file"`
done
So… where is my problem?
Thanks everyone :)
Upvotes: 0
Views: 100
Reputation: 16059
That is because the for loop will take every word inside the result of the find as an element to iterate over. for
will see it as:
for file in {/my/good/path/MY, -, AWFUL, FILE.DOC}
echo "$file"
done
And will print:
/my/good/path/MY
-
AWFUL,
FILE.DOC
One solution to this problem is to use the xargs
program to pass the result of the find
as your python program argument:
find "/my/pash" -name "*.DOC" -print0 | xargs -0 -i program "{}"
Upvotes: 1
Reputation: 247210
Some correct answers, but no explanations so far:
a for
loop is intended to iterate over words not lines. The given (unquoted) string is subject to word splitting (which is what is troubling you) and filename expansion, and then you iterate over the resulting words. You could set IFS to contain only a newline. The safest way is to use find -print0
and xargs -0
as demonstrated by Vytenis's answer
Upvotes: 2
Reputation: 28059
#!/usr/bin/bash
find "/my/pash" -name "*.DOC" | while read file; do
newvar="$(program "$file")"
done
Note that this only fixes the case where a space or tab is in the file name. If you have a newline in the file name, it gets a little more complicated.
Upvotes: 1
Reputation: 2081
the loop treats blanks as delimiter, so try this one:
find "/my/pash" -name "*.DOC" | while read file; do
newvar=`program "$file"`
done
Upvotes: 0