How can I search for files in directories that contain spaces in names, using find
?
i use script
#!/bin/bash
for i in `find "/tmp/1/" -iname "*.txt" | sed 's/[0-9A-Za-z]*\.txt//g'`
do
for j in `ls "$i" | grep sh | sed 's/\.txt//g'`
do
find "/tmp/2/" -iname "$j.sh" -exec cp {} "$i" \;
done
done
but the files and directories that contain spaces in names are not processed?
Never used
for i in $(find...)
or similar as it'll fail for file names containing white space as you saw.Use
find ... | while IFS= read -r i
instead.It's hard to say without sample input and expected output but something like this might be what you need:
The above will still fail for file names that contains newlines. If you have that situation and can't fix the file names then look into the
-print0
option forfind
, and piping it toxargs -0
.Do it like this
find . -type f -name "* *"
Instead of
.
you can specify your path, where you want to find files with your criteriaUse
while read
loop with null-delimited pathname output fromfind
:This will grab all the files that have spaces in them
I don't know how to achieve you goal. But given your actual solution, the problem is not really with
find
but with thefor
loops since "spaces" are taken as delimiter between items.find
has a useful option for those cases:As the man saids, this will match with the
-0
option ofxargs
. Several other standard tools have the equivalent option. You probably have to rewrite your complex pipeline around those tools in order to process cleanly file names containing spaces.In addition, see bash "for in" looping on null delimited string variable to learn how to use for loop with 0-terminated arguments.
Your first for loop is:
If I understand it correctly, it is looking for all text files in the
/tmp/1
directory, and then attempting to remove the file name with thesed
command right? This would cause a single directory with multiple.txt
files to be processed by the inner for loop more than once. Is that what you want?Instead of using sed to get rid of the filename, you can use
dirname
instead. Also, later on, you use sed to get rid of the extension. You can usebasename
for that.This doesn't solve the problem of having a single directory processed multiple times, but if it is an issue for you, you can use the for loop above to store the file name in an array instead and then remove duplicates with
sort
anduniq
.