Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unix 'find' + 'grep' syntax vs. awk

I was using this line to find the phrase, 'B206' within files in the directory I was in and all of its sub directories.

find . -exec grep -s "B206" '{}' \; -print 

It crashes when it tries to read certain files and actually changes the title bar in putty to a bunch of weird characters

For example, it crashes all the time when it hits a jpg file that's in a sub directory. The title bar changes, and in the screen, there exists:

ÐF»*rkNQeË+Z׳kU£~MÞçÄZ½ªéúýØâÑn¡[U+Þ4ªÒ9/ê£<ú¯4}[IÓ­îÃ¥K»G%ݳ¢

Forcing me to Ctrl+C out back to the prompt and then exit out.

Any way to add code to this line that will exclude jpg files? Even better, a piece of code where I can add a list of extensions to exclude?


EDIT:
-not & -I do not work for me
I found this similar question also related somewhat to mine
like image 296
CheeseConQueso Avatar asked Nov 27 '22 15:11

CheeseConQueso


2 Answers

There's no reason to use find: grep comes with a recursive option, -r. To just get a list of the filenames with matches (as opposed to a list of all of the matching lines in all the files), you can use the -l option. If you want to ignore all binary files outright, you can use --binary-files=without-match option. If you only want to ignore files with a certain extension, you can use the --exclude option, e.g. --exclude=*.{jpg,jpeg} to ignore all files ending in .jpg or .jpeg. Thus, you should be able to get what you want with this:

grep -r -l --binary-files=without-match .

Now, you mentioned in one of your comments that your version of grep doesn't have the -r or -l options. That's unfortunate, and I recommend getting a more recent version of grep (preferably of the GNU variety).

One further note: if you use find -exec, you should use a + to end the command instead of a semicoln, e.g.:

find . -exec grep options '{}' '+'

By using a +, find will only fork off a single process and pass all of the matching filenames as command line arguments to one instance of grep. So long as you don't have a million matching files (which would create a command line far longer than the shell can handle), this will be much, much faster. If you use a semicolon instead, find forks a new process for each matching file, which is really slow for a very large number of files.

like image 87
Adam Rosenfield Avatar answered Dec 04 '22 04:12

Adam Rosenfield


If your environment can't do any fancy grep, maybe your awk can do it:

find . | awk '!/((\.jpeg)|(\.jpg)|(\.png))$/ {print $0;}' | xargs grep "B206"
like image 30
phi Avatar answered Dec 04 '22 03:12

phi