Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Imagine a source tree. There are xml files everywhere.

But since there is a XYZ.xml at the root of this tree it won't find my xml files.

find -iname *.xml

returns

./XYZ.xml

instead of

./XYZ.xml
./a/b/c/bob.xml
./b/d/top.xml
share|improve this question
    
From man find: Please note that you should quote patterns as a matter of course, otherwise the shell will expand any wildcard characters in them. –  artdanil Jun 29 '12 at 17:50

4 Answers 4

up vote 12 down vote accepted
find -iname '*.xml'

Otherwise, your shell expands *.xml to XYZ.xml, and the command that actually gets executed is

find -iname XYZ.xml

The reason it works if there are no XML files in the current directory is that shells generally leave wildcards unexpanded if they don't match anything. In general, any time you want wildcards to be expanded by a program other than the shell (e.g. by find, tar, scp, etc.) you need to quote them so the shell won't try to expand them itself.

share|improve this answer
1  
Thx, that's so simple, but I've been wondering how to get around that for months. I found that really weird, and to be a very inconsistent behavior, but now I understand since it's not find, but bash's fault. –  Olivier Toupin May 29 '11 at 1:47
1  
It's not bash's "fault" per-se but yours for not quoting wildcards that you wanted to pass as arguments. This goes for all programs that accept shell input. The shell expands them as globs unless they are quoted or escaped. –  Caleb May 29 '11 at 5:59
1  
I guess Olivier meant it in the meaning, that it is an issue of bash, not of find. –  user unknown May 29 '11 at 14:03

You need to quote your argument like this:

find ./ -name '*.xml'

so that it gets passed to find instead of being expanded by the shell, then passed to find as the expanded version.

share|improve this answer
1  
Ok, so if *.xml doesn't match anything in the current directory, it is passed on literally, which is why it works in the other case. Very helpful answer. –  Eric Wilson Jun 9 '11 at 13:17

Please try:

find ./ -name *.xml
share|improve this answer
    
I've just tried that, same result. –  Eric Wilson Jun 9 '11 at 13:07
    
I've tried it, and it works. On GNU bash 4.2.8 –  bbaja42 Jun 9 '11 at 13:13
3  
This doesn't work when the glob matches anything in the current directory. It is the wrong syntax! The * should always be quoted or escaped to pass it to find. –  Caleb Jun 9 '11 at 13:15

This works on Solaris 10:

find /directory-to-search/* -prune -name "*gz"

share|improve this answer

Your Answer

 
discard

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.