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.

If I want to list files by date containing "foo" in the file name, I can do either of the following
find . -name "*foo*" -exec ls -lrt {} \;
ls -lrt $(find . -name "*foo*")

If I want to list files by date containing "foo" inside the file itself, I can only do
ls -lrt $(grep -rl "foo")

Also, grep -l returns a list of files, for example
file1
file2
file3
And the list will be a different colour than default colour

Wheras find returns a list, in the default colour, like this
./file1
./file2
./file3

So what's going on here? What's with the difference between the two results, and why can't I exec the result from grep?

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

Your first two proposed commands are not equivalent. If you use find to -exec ls, what happens is that find will run ls once for each file. The output order will be the order found by find, not ls. Because ls is being run one-file-at-a-time, it doesn't know how to line up the columns. For example, done here in Cygwin bash:

Nicole@NicoleDesktop ~/HamiltonCshell/Current/util
$ find . -name "s*.c" -exec ls -lrt {} \;
-rwx------+ 1 Nicole None 104826 Dec 29  2010 ./Archive/su.2010-12-29/su.c
-rwx------+ 1 Nicole None 107074 Aug  2  2011 ./Archive/su.2011-08-29/su.c
-rwx------+ 1 Nicole None 125359 Jul 17 11:47 ./sed.c
-rwx------+ 1 Nicole None 15517 Oct  6  2011 ./setrows.c
-rwx------+ 1 Nicole None 8454 Oct  8  2011 ./setwin.c
-rwx------+ 1 Nicole None 39007 Jan 24  2012 ./shortcut.c
-rwx------+ 1 Nicole None 4655 May 22  2009 ./showdesk.c
-rwx------+ 1 Nicole None 66906 Nov 20 09:58 ./sort.c
-rwx------+ 1 Nicole None 9702 May 22  2009 ./split.c
-rwx------+ 1 Nicole None 21306 May 22  2009 ./strings.c
-rwx------+ 1 Nicole None 113680 Jul 15 06:56 ./su.c
-rwx------+ 1 Nicole None 10076 May 23  2009 ./sum.c

If you use command substitution, the shell will paste the list produced by find back onto the command line as arguments to ls and then it will run ls exactly once on the entire list of files and result will indeed be ordered by date, newest first.

Nicole@NicoleDesktop ~/HamiltonCshell/Current/util
$ ls -lt $(find . -name "s*.c")
-rwx------+ 1 Nicole None  66906 Nov 20 09:58 ./sort.c
-rwx------+ 1 Nicole None 125359 Jul 17 11:47 ./sed.c
-rwx------+ 1 Nicole None 113680 Jul 15 06:56 ./su.c
-rwx------+ 1 Nicole None  39007 Jan 24  2012 ./shortcut.c
-rwx------+ 1 Nicole None   8454 Oct  8  2011 ./setwin.c
-rwx------+ 1 Nicole None  15517 Oct  6  2011 ./setrows.c
-rwx------+ 1 Nicole None 107074 Aug  2  2011 ./Archive/su.2011-08-29/su.c
-rwx------+ 1 Nicole None 104826 Dec 29  2010 ./Archive/su.2010-12-29/su.c
-rwx------+ 1 Nicole None  10076 May 23  2009 ./sum.c
-rwx------+ 1 Nicole None  21306 May 22  2009 ./strings.c
-rwx------+ 1 Nicole None   9702 May 22  2009 ./split.c
-rwx------+ 1 Nicole None   4655 May 22  2009 ./showdesk.c
share|improve this answer
add comment

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.