script problem
I am trying to copy a set of files which I want to select with find.
A simplified example would be: for i in `find . -mtime 5`; do cp $i /dest/; done The problem is that some of the files i select contain spaces. Such a filename is interpreted by the for command as separate words, and the resuls are that cp gets only parts of the filename at a time. How can I solve this best ? My first ideas were to redefine $IFS to only include newlines, but this may result in problems later on (in reality i do more complex things between do and done). The next idea was to somehow format the output of find so that each filename would be quoted "my filename", but I think the shell would interprete these quotes as \"my filename\" . The best thing would be if I could make find return my\ filename, but I don't know how to do that. Any ideas ? |
Re: script problem
Quote:
Cheers, Tink |
The apostrophes may be required too, but it's not sufficient.
have a look at the output of for i in `find . -type f -name 'm*'`; do echo "$i"; done in a folder containing my_filename and my\ filename ./my_filename ./my filename As you can see, the loop is run three times, so the problem is not with the specific command within the do loop, but in the way the for loop interprets the output of the find command. |
That *will* work:
1) find . -mtime 5 -print | while read i; do cp "$i" /dest/; done or those *may* work (to be tested): 2) find . -mtime 5 -exec cp {} /dest/ \; 3) cp $(find . -mtime 5 -printf "\"%p\" ") /dest/ Yves. |
4) find . -mtime 5 -print0 | xargs -iXX -0 cp XX /dest
|
Excellent! You just showed me how to "correct" the two shortcommings I thought were in xargs (and were not in fact): XX is for being able to append args to the stdin args, isn't it? And print0 and -0 are for separating args by nul instead of blank (à-la C), right?
Thanks :) Yves. |
yes, -i specifies the substitute argument name, which came from stdin
|
an easy solution is to temporarily tell bash not to consider space to be a separator:
export IFS=$'\t\n' # tab and newline for $i in `ls *`; do cp $i /dest/; done export IFS=$' \t\n' # space tab and newline |
All times are GMT -5. The time now is 11:53 PM. |