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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.