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.javawhich 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.javaSince 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 2 You 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/fileThis 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/fileThis will match all the filename staring with file
[max@localhost ~]$ find -name "1file"
./1fileThis 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