need find output to escape spaces

Brazen

Diamond Member
Jul 14, 2000
4,259
0
0
I have a script like this:

for directory in $( find /afolder/ -maxdepth 1 -type d ); do
echo $directory
done

The problem is if I have a foldername with spaces in it such as "/afolder/this and that/" then it ends up splitting it into three variables, so the output is:

/afolder/this
and
that

When I really need the output to be:

/afolder/this\ and\ that

I've played around with find's output formatting options but I can't find anything to have it escape the space character.
 

Fallen Kell

Diamond Member
Oct 9, 1999
6,119
482
126
Well, for one thing, why don't you just do "find /afolder/ -maxdepth 1 -type d -print" which will do exactly what your script is doing? If you need to do more than just print, look at the -exec option of find which will execute a command or commands on each of the results of the find. Baring all that, you could also pipe the find command's output to a sed command to replace the space with a \space... something like:

for directory in $( find /afolder/ -maxdepth 1 -type d | sed 's/ /\ /g'); do

Or you could pipe it to a "tr" to do a transcode of the space characters, or a perl script which splits the input line on spaces and put the pieces in an array, and then joins that array back together with a "\ " and then prints the result.... I could go on and on... But as I said the best way is to just use the find "-print" option especially if all you are doing is an echo. And even if you want to do more, use the find -exec option for anything more complex.
 

Nothinman

Elite Member
Sep 14, 2001
30,672
0
0
Or how about -print0 and use xargs -0 to run whatever command you want on each entry?
 

Brazen

Diamond Member
Jul 14, 2000
4,259
0
0
Originally posted by: Fallen Kell
Well, for one thing, why don't you just do "find /afolder/ -maxdepth 1 -type d -print" which will do exactly what your script is doing? If you need to do more than just print, look at the -exec option of find which will execute a command or commands on each of the results of the find. Baring all that, you could also pipe the find command's output to a sed command to replace the space with a \space... something like:

for directory in $( find /afolder/ -maxdepth 1 -type d | sed 's/ /\ /g'); do

Or you could pipe it to a "tr" to do a transcode of the space characters, or a perl script which splits the input line on spaces and put the pieces in an array, and then joins that array back together with a "\ " and then prints the result.... I could go on and on... But as I said the best way is to just use the find "-print" option especially if all you are doing is an echo. And even if you want to do more, use the find -exec option for anything more complex.

Yes, there is actually a whole lot more that I have to do with the results, to the point that I don't think I will be able to use -exec without getting creative (which I may resort to) and also rewriting a bunch of code. I may just port the script to Ruby before going that route.

I really thought the sed solution would work after you mentioned it, but unfortunately I now just get output like this:

/afolder/this\
and
that
 

Fallen Kell

Diamond Member
Oct 9, 1999
6,119
482
126
Perl might be your key then....

---------------------------------------------------------------------
#!/bin/perl

my $start_path = shift;

# Check that the argument was a directory
if (-d $start_path) {
process_dir($start_path);
}

sub process_dir {
my $dir = shift;

#Run find command
my $tmp = `find $dir -type d`;
chomp($tmp);


#Split the output into a perl array
my @dirs = split(/\n/, $tmp);

#Loop over the output from the find
foreach my $d (@dirs) {
#If the output has spaces
#escape the spaces
if ($d =~ / /) {
my @tmp = split(/ /, $d);
$d = join("\\ ", @tmp);
}
#Prints the output and puts a newline
#character at the end
print "$d\n";
}

}

------------------------------------------------------------

Perl is your friend.... If you look at the above, note that you can run any system call with by putting a ` around it, as I did for the find command. You can save that output from the command to a variable just like I did, and of course, do the chomp on the variable as well, otherwise, you will have a newline character at the end that you don't want to deal with...