I was looking for differences in the find command with double quotes and without quotes.
I found something odd. I have two files:
xWrapper.javaYWrapper.java
and some in the pattern *Wrapper.java.
I ran
find . -name *Wrapper.java which should return the first file that matches the pattern, because the command expands as
find . -name xWrapper.java yWrapper.java .. But as a result, I got the all the files of that form. Why did it return all the files matching that pattern?
13 Answers
If anything you should get an error message if you are in the same catalog:
~$ mkdir test ~$ cd test ~/test$ touch {X,Y}Wrapper.java ~/test$ find . -name *Wrapper.java find: paths must precede expression: YWrapper.java Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression] since the asterisk will be expanded, and -name only takes a single argument.
If you come from a location where the asterisk is not expanded:
~/test$ cd .. ~$ find test -name *Wrapper.java test/XWrapper.java test/YWrapper.java Since the asterisk is now not expanded (as long as it does not match anything in the current directory), find sees it "as is", and uses it as a wildcard.
You should wrap the -name argument in single quotes to avoid such context dependent behavior:
~/test$ find . -name '*Wrapper.java' ./XWrapper.java ./YWrapper.java 2You can use the or function because -name is a single string argument.
find . \( -name "xWrapper.java" -o -name "yWrapper.java" \) Or you can use regex to find the file with
find . -regex '.*\(x\|y\)Wrapper.java' 1[max@localhost ~]$ touch 1file [max@localhost ~]$ touch 2file [max@localhost ~]$ touch 3file [max@localhost ~]$ touch 4file [max@localhost ~]$ touch 5file [max@localhost ~]$ find -name "*file" ./4file ./2file ./Desktop/new file ./Desktop/DESKTOP/new file ./.bash_profile ./#file ./3file ./1file ./5file ./file ./file/file This will match all the filename ending with file
[max@localhost ~]$ find . -name 'file*' ./file1 ./.gconf/apps/file-roller ./Downloads/ ./Downloads/ ./Downloads/ ./.gnome2/file-roller ./.local/share/Trash/files ./file ./file/file2 ./file/file This will match all the filename staring with file
[max@localhost ~]$ find -name "1file" ./1file This will match only filename 1file
[max@localhost ~/avi]$ touch a [max@localhost ~/avi]$ touch b [max@localhost ~/avi]$ touch "a b" [max@localhost ~/avi]$ ll total 0 -rw-rw-r-- 1 max max 0 Jul 31 13:49 a -rw-rw-r-- 1 max max 0 Jul 31 13:49 a b -rw-rw-r-- 1 max max 0 Jul 31 13:49 b [max@localhost ~/avi]$ find . -name a ./a [max@localhost ~/avi]$ find . -name b ./b [max@localhost ~/avi]$ find . -name a b find: paths must precede expression: b Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression] [max@localhost ~/avi]$ find . -name "a b" ./a b (" or ') symbol will useful when there is a space in between filename like "a b"
1