Difference between 'ls -ltr abc*' and 'find ./ -name abc*' command?
Solution 1
ls -ltr file*
: This command just list the contents of the current directory in the long listing format (-l
), sorted by modification time (-t
) in reverse order (-r
) of all files and directories beginning withfile*
.find ./ -name file*
: That command searches trough the whole directory structure under the current working directory and all its subdirectories for files and directories beginning withfile*
in their names. The output format is very simple; only the file/dir paths are printed line by line.
Major difference (conclusion):
ls
only applies to the current working directory, while find
applies to all files and subdirectories starting from the current working directory.
Solution 2
The find
version will also find files matching that name in subdirectories.
Note you should quote or escape the *
in the filename pattern; if the pattern matches a file in the local directory it will expand to that name and find
will only find exactly that name. If it matches more than one filename then you will get an error because those multiple filenames will replace the pattern in the find
invocation and that doesn't match find
syntax. E.g.:
$ cd /etc
$ find . -name pass*
find: paths must precede expression: passwd-
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
$ find . -name 'pass*'
./passwd
./passwd-
./pam.d/passwd
./cron.daily/passwd
Solution 3
The shell will do filename expansion before either command is executed, so the results depends on what is in your current directory.
To get what you want, I think you wouldwant to quote the *
in the find command. check this example.
# First show all the files
~/tmp/stack $ find .
.
./dir1
./dir1/FileA
./dir1/FileB
./dir1/FileC
./dir1/filec
./dir2
./dir2/filea
./dir2/fileb
# Following will list nothing because there is no file named File* in the current directory
~/tmp/stack $ ls -lR File*
ls: cannot access File*: No such file or directory
# Now using find will work because no file named File* exists, file name
# expansion fails, so find sees the * on the command line.
~/tmp/stack $ find . -name File*
./dir1/FileA
./dir1/FileB
./dir1/FileC
# I'll create a file named Filexxx
~/tmp/stack $ touch Filexxx
# ls will work but only list details for Filexxx
~/tmp/stack $ ls -lR File*
-rw-rw-r-- 1 christian christian 0 Apr 21 09:08 Filexxx
# and so will find but probably not as expected because filename expansion works, so actual command executed is find . -name Filexxx
~/tmp/stack $ find . -name File*
./Filexxx
# now escape the wild card properly, then find will work as expected
~/tmp/stack $ find . -name File\*
./dir1/FileA
./dir1/FileB
./dir1/FileC
./Filexxx
~/tmp/stack
Related videos on Youtube
![ursitesion](https://i.stack.imgur.com/4vySF.jpg?s=256&g=1)
ursitesion
Updated on September 18, 2022Comments
-
ursitesion almost 2 years
To search a file in a directory, I found two commands as below:
- ls -ltr initialfilename*
- find ./ -name initialfilename*
Sometime, first command gives me the search result but sometime I used to execute second command. What is the difference between these two set of Linux command? Please specify your answer around the major difference only.
-
ursitesion about 9 yearsYour answer is better than all but not what I was looking for.
-
ph0t0nix about 9 yearsursitesion: The answer from @chaos exactly describes what the two commands to and how their outputs differ. If this is not what you had in mind, please give a better explanation of what you are looking for. And how about running these commands and seeing the differences for yourself?
-
Janis about 9 years+1 for "the results depends on what is in your current directory".
-
wurtel about 9 yearsIf you quote the filename pattern with
ls
then that's expected, therels
does no expansion of filenames but depends on the shell in such cases. In the case offind
I find it hard to believe that you didn't get any result.. -
Atul over 4 yearsls only applies to the current working directory is this correct statement? How about
ls -R
?