Shell command to list file names where the matching is found


Shell command to list file names where the matching is found



I am trying to search through a list of binary files to find some keywords on Mac.



The following works to list out all the matches, but it doesn't show me the list of files where it is being found:


find . -type f -exec strings {} ;|grep "Bv9qtsZRgspQliITY4"



Is there any trick to do this?





Do you still want to print the matches, or just the files’ names/paths?
– Biffen
Jun 29 at 10:07




5 Answers
5



Using -exec with a wee ‘script’:


-exec


find . -type f
-exec sh -c 'strings "$1" | grep -q "Bv9qtsZRgspQliITY4"' -- {} ;
-print



The above will print the paths of all the matching files. If you also want to print the matches you can use:


find . -type f
-exec sh -c 'strings "$1" | grep "Bv9qtsZRgspQliITY4"' -- {} ;
-print



This will, however, print the paths after the matches. If this is not desirable, then you can use:


find . -type f
-print
-exec sh -c 'strings "$1" | grep "Bv9qtsZRgspQliITY4"' -- {} ;



This, on the other hand, will print all paths, even non-matching ones. To print only matching paths and their matches:


find . -type f
-exec sh -c 'strings "$1" | grep -q "Bv9qtsZRgspQliITY4"' -- {} ;
-print
-exec grep "Bv9qtsZRgspQliITY4" {} ;



This will run grep twice on matching files, which will make it slower. If this is a problem the matches can be stored in a variable, and if there are any the path printed first and then the matches. This is left as an exercise to the reader.*


grep



* Let me know if I should post it here.





I've tested this one, but didn't display the content of the file.
– Miguel Ortiz
Jun 29 at 10:04





I thought the user wanted both things, filenames and below the strings printed. In that case grep already does that.
– Miguel Ortiz
Jun 29 at 10:12





True, what about this: $ grep -arl . -e 'soloman' | tee | strings --print-file-name In this case you could redirect to strings and process there?
– Miguel Ortiz
Jun 29 at 10:24



$ grep -arl . -e 'soloman' | tee | strings --print-file-name



Try grep -rl "Bv9qtsZRgspQliITY4" ..


grep -rl "Bv9qtsZRgspQliITY4" .



Explanation of options:


-r


-l



Optionally, you might want to use -i to search case-insensitively.


-i



The problem with your idea is that you're piping the output of strings into grep. The filename is only passed to strings, meaning that nothing that comes after strings knows the filename.


strings


grep


strings


strings



I'm not quite sure about portability, but if you are using GNU's version of grep, then you can use --files-with-matches


--files-with-matches


-l, --files-with-matches print only names of FILEs containing matches



Then you can use something like this:


grep --recursive --files-with-matches "Bv9qtsZRgspQliITY4" *





You’re missing the whole strings thing. This probably won’t work.
– Biffen
Jun 29 at 9:43


strings





FYI, -l is portable (POSIX), but --files-with-matches is not (GNU).
– Biffen
Jun 29 at 9:45


-l


--files-with-matches





GNU grep will search binary files. If you want to be explicit about it you can pass -U to specify a binary search. so the strings command and the associated find command are superfluous.
– iLoveTux
Jun 29 at 13:46


-U


strings


find





But strings’s output is not the same as the contents of the file, so greping it is not the same as greping the file, binary or not.
– Biffen
Jun 29 at 13:49


strings


grep


grep





I agree, but the OP only wants to find filenames so the differences are not going to affect the output. Also earlier I said -U I meant to say -a.
– iLoveTux
Jun 29 at 13:54


-U


-a



Well, if it's only to print names of files don't use find but grep.


grep -ar . -e 'soloman' ./testo.txt:1:soloman



And keep it simple.



If you don't want to see the words matched in your output simply add -l, --files-with-matches:


-l, --files-with-matches


user@DESKTOP-RR909JI ~/projects/search
$ grep -arl . -e 'soloman'
./testo.txt



You can use


# this will list all the files containing given text in current directory
# i to ignore case
# l to list files with matches
# R read and process all files in that directory, recursively, following all symbolic links
grep -iRl "your-text-to-find" ./

# for case sensitive search
grep -Rl "your-text-to-find" ./





Adding -i could lead to incorrect strings in the search of the user.
– Miguel Ortiz
Jun 29 at 9:18





@MiguelOrtiz thanks for correction :)
– nandal
Jun 29 at 9:21





@nandal You’re missing the whole strings thing. This probably won’t work.
– Biffen
Jun 29 at 9:43


strings





@nandal this won't work for binary files.
– Miguel Ortiz
Jun 29 at 10:30





@John, thank you, fyi, this prints out the file names, without the matches.
– sqr
Jun 29 at 14:36







By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift