Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I'm trying to use find to list dirs with a certain file inside, but my dirs have spaces so I haven't found a solution.

share|improve this question

migrated from serverfault.com Apr 22 '11 at 10:31

This question came from our site for professional system and network administrators.

1  
It's not clear what you want to do. Can you be more specific? –  Dennis Williamson Mar 15 '11 at 4:17
    
If you're worried about compatibility, wouldn't a simple perl script using the standard File:Find module instead? That would probably work reliably on any platform. –  Phil Hollenback Mar 15 '11 at 6:42
    
Phil, I'm not a perl programmer i'm a python programmer. –  Anonymous Mar 16 '11 at 17:17

4 Answers 4

Assuming I'm really understanding your question, have you tried:

find / -name "*what*" -exec dirname {} \;

This works for me even if my directories have spaces:

root:~# find / -name "*what*" -exec dirname {} \;
/usr/share/man/id/man1
...
...
/usr/share/man/ja/man1
/usr/share/man/it/man1
/usr/share/man/man1
/usr/bin
/root/This is a Spaced Dir
share|improve this answer
    
This doesn't work on OS X –  Anonymous Mar 16 '11 at 17:18

This is from the fedora .bashrc file:

ff () {
       find . -name "*$@*" -print;
       }

Add this to your .bashrc and then reinitialize your bash shell

now you can use ff <whatever > \ <whatever>

The \ is the escape sequence to escape special characters.

share|improve this answer

POSIX dictates a rather weak find (seriously, it doesn't even have -print0). Likewise, xargs won't have an -0 option, and IEEE 1003.1-2008 considers xargs -I {} to be an X/Open System Interface extension (which both declares a string to substitute with arguments and converts xargs to using newlines for input argument separators). Thus, assuming you actually want to do something with the path names other than printing them out and if you can only use base POSIX, you'll need to escape the spaces in the strings before passing them to xargs, thus:

find /startingdir -name 'file name' -exec dirname {} \; | sed 's/ /\\ /g' | xargs command

Note that you'll also need to escape quotes and backslashes, if you have directories that include these. This could replace the sed command:

sed -e 's/\\/\\\\/' -e 's/ /\\ /g' -e 's/"/\\"/g' -e "s/'/\\\\'/g"

(Note the extra backslashes on the double quoted script. Single quote strings use backslashes literally, but double quote strings will interpret backslashes, thus your shell will interpret "\\\\" as \\ which sed needs for a literal \, while '\\\\' is interpreted as \\\\ which sed needs for a literal \\.) This will escape existing backslashes first, then escape spaces, double quotes and single quotes.

If you can use the X/Open System Interface extensions, then the first version (no quotes or backslashes) simplifies to:

find /startingdir -name 'file name' -exec dirname {} \; | xargs -I {} command {}

If you have quotes and backslashes in your directory names, these will still need to be escaped as above (but without escaping spaces).

Either way, if you have newlines in your directory names, then you've got bigger problems than I can help with.

Edited to remove bash version, cleaned up based on input from Dennis Williamson

share|improve this answer
    
There are many errors in your answer. To start with, your assignment to IFS won't work. You should never iterate over the output of find using a for loop. If you want to be portable and POSIX compliant, don't use echo. You could use sed, but why not use dirname. In one place you use $() which is specified by POSIX, but in another you use backticks which, while also POSIX, are less desirable. You fail to mention the find operator -exec. You fail to quote a variable containing a filename. The question is tagged [posix] but not tagged [bash] so sh should be assumed. –  Dennis Williamson Mar 15 '11 at 4:17
    
OK, I'll clean this up, though I'll be leaving it written for the assumption that he wants to do something with the list of directories, rather than just displaying them (otherwise, would it really merit mentioning spaces as a problem?). I'll even take out the bash version of my answer, which I had written before seeing the posix tag. –  DerfK Mar 15 '11 at 5:34
    
Thanks, your first example worked. Now that I think about it sed would work for escaping spaces. –  Anonymous Mar 16 '11 at 17:14

zsh is not my preferred shell, but for this task its **-function is invincible:

zsh -c "'ls **/'the file name'"

Or even:

zsh -c "ls **/*'file name'"
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.