How do I deal with directories that have spaces in their names from `find`?

19,346

Solution 1

Something like the following works ...

find . -type d | while read dir; do echo $dir; done
.
./my dir

Depending on what you're doing, you might be better using find's -print0 option and xargs -0.

The code you've got takes the unquoted output from find and uses it as a list of words (split on whitespace) for for to iterate over.

Solution 2

Do not use for loop, use while instead:

find . -type d -print0 | while read -d '' -r dir; do echo "$dir"; done

Option print0 prints NULL character at the end of file/directory name (instead of newline) and read -d '' interprets it properly.

Solution 3

You can just use "$file" in your example.

Solution 4

If you're really just looking to echo the results of find, you can use the parameter -print (or just no additional parameter at all) to have find print a list of its results.

If you want to delete the results, there's -delete (which can be combined with -print to get a list of the deleted files).

If you want to do something else with/to the results, you can use the parameter -exec to pass the results as parameters to another command, e.g.

  • find . -type d -exec tar cf {}.tar {} \; to compress all directories into individual tarballs (one tar per directory, since \; makes find run the -exec command with one result at a time)
  • find . -type d -exec tar cf all-directories.tar {} + to compress all directories into a single tarball (+ makes find run the -exec command with as many results as possible at a time)

Solution 5

You have to set IFS variable in bash:

SAVEIFS=IFS
IFS=$(echo -en "\n\b")
...
YOURCODE
....
IFS=$SAVEIFS

But what does above code do? , it discard any space and meta char..

Share:
19,346

Related videos on Youtube

Almo
Author by

Almo

Programmer, game designer, master's in physics. Cognizer: my latest game on iOS, Android, Steam and the web version at Kongregate. Free download! Maniac Games, my video game endeavor: http://www.maniac-games.com/ Maniac Games forum: http://www.maniac-games.com/forum Linkage, my published boardgame: http://nestorgames.com/#linkage_detail

Updated on September 18, 2022

Comments

  • Almo
    Almo over 1 year

    I have this:

    #!/bin/bash
    
    for file in `find . -type d`
    do
      echo $file
    done
    

    If I have just one directory called My Directory, the output is

    My
    Directory
    

    How do I fix this?

    The echo $file is just temporary. There will be other code in there operating on the directories.

  • Almo
    Almo over 9 years
    This doesn't actually work. The for breaks it up before it gets there.
  • Almo
    Almo over 9 years
    I'll be doing an xattr to remove resource forks on OSX with this. Question edited, thanks.
  • adamantly
    adamantly over 9 years
    What do you mean breaks it up? Using echo "$file" works for me.
  • cuonglm
    cuonglm over 9 years
    This assumes that you use GNU find of BSD find.
  • Almo
    Almo over 9 years
    Echo "$file" works on one variable. But in this loop, the for $file has already broken the output of the find command in to a list of strings that were split by spaces. So it's too late already by the time it gets to the echo command.
  • syntaxerror
    syntaxerror over 9 years
    Maybe it would be a good idea to issue a warning about -delete! Like deltree on DOS prompt in Windows, this seemingly inconspicuous option can cause huge file trees to get purged in no time!! So use -delete with extreme caution.
  • syntaxerror
    syntaxerror about 9 years
    Just to make one thing clear: for the OP's question, the for loop is indeed unnecessary BUT ... it is not necessarily redundant, especially not for bash beginners. For example, if you use two loop variables i and j (with j being an altered i) or simply a couple different statements, the for loop approach (though frowned upon) is easier to comprehend than teaching them the pro solution of -exec sh -c ... which is as if you attempted to teach calculus to a person that only ever learned about basic arithmetics.