2

When I run this command ls -l Documents/phone_photo_vids, I get 100s of entries in the following format. Notice the endings of the images are either PNG or JPG

-rw-r--r--  1 moi  staff      189280 Oct 29  2011 IMG_0041.PNG
-rw-r--r--  1 moi staff     2481306 Oct 29  2011 IMG_0042.JPG

I then decided that I only wanted to see the jpg results, so I ran both of these commands, both of which returned no results

 ls -l Documents/phone_photo_vids | grep "*.JPG"
 ls -l Documents/phone_photo_vids | grep "*.JPG$"

I would have expected both of the grep commands to filter out all the files ending in PNG, and return all the files ending in JPG, but I got nothing. How am I using grep incorrectly?

I'm working on a Mac OSX 10.9.3

2
  • try ls -l Documents/phone_photo_vids | grep ".JPG"
    – Tyson
    Sep 5, 2014 at 2:09
  • 1
    Why use grep at all anyway? Why not just ls -l Documents/phone_photo_vids/*.jpg?
    – lzam
    Sep 5, 2014 at 2:10

4 Answers 4

0

Some form of answers are WRONG although it works like it claims most of the time.

grep ".jpg"    #match string "jpg" anywhere in the filename with any character in front of it.
               # jpg -- not match
               # .jpg -- match
               # mjpgsfdfd -- match
grep ".*.jpg"  #basically the same thing as above
grep ".jpg$"   #match anything that have at least 4 chars and end with "jpg"
               # i_am_not_a_.dummy_jpg -- match
grep ".*.jpg$" #the same as above (basically)

So to have the best result, try these ones:

grep "[.]jpg$" #anything that end with ".jpg"
grep "\\.jpg$" #the same as above, use escape sequence instead
2

As others have said, you are trying to use shell wildcards (*) within grep, where the wildcard for a single character is the dot (.). Patterns of .JPG would match xxx.NOTAJPG or NOTAJPG.txt if there were such a thing.

The better solution is to just say:

ls -l Documents/phone_photo_vids/*.jpg

If you want case-insensitivity

ls Documents/phone_photo_vids/*.{jpg,JPG}

which is the same as saying ls *.jpg *.JPG

It is not recommended, but if you really want to get it working with grep, just specify files ending with jpg and maybe make it case insensitive with -i. You don't need all the '.*.' stuff.

ls -l Documents/phone_photo_vids | grep -i jpg$
1

Grep uses what is called regex, not what DOS or Windows uses for searches.

The regex expression "*.JPG$" makes no sense to grep, so it probably ignores it. What you want is ".*JPG$"

For reference.

1

Try the following:

grep "jpg"    #match string "jpg" anywhere in the filename, so file "img.jpg.txt" match too
grep ".*jpg"  #match the whole line with string "jpg", here ".*" stands for any char zero or more times
grep "jpg$"   #match string "jpg" only at the end of line ("img.jpg.txt" will not match)
grep ".*jpg$" #match the whole line only if "jpg" is at the end of line
grep "\.jpg"  #match string ".jpg" - to search literaly for dot one need to escape it with backslash

You can create temporary files with touch "img.jpg.txt" ".jpg" and use grep --color=always to see how above patterns change the output.

BTW, parsing ls is usually not good idea, better use find:

find /path/to/files/ -maxdepth 1 -type f -iname '*.jpg'
3
  • I thing this is actually wrong: grep ".jpg" matches anything contains "jpg" and have at least 1 char in front of it. So for the others. Am I right? Sep 5, 2014 at 3:34
  • You are right, thanks for pointing this, I've edited my answer.
    – jimmij
    Sep 5, 2014 at 4:19
  • There really is no point in any of the .* stuff for the purposes of this question. Zero or more characters is the same as matching jpg by itself.
    – beroe
    Sep 5, 2014 at 4:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .