Searching files and content with find and xargs
.txt files with the word “foo” in them. Prepended with the filenames.
Usually I use
grep only with standard input but in this case we would lose the
file path if we did that. So
xargs to the rescue! It takes the output of the
previous command and add it to the last argument to the next. Beautiful and simple magic! 🔮
find / -name *.txt -print0 | xargs -0 grep -H "foo"
-type f is saying that we only want to search for regular files.
find . -type f -print0 | xargs -0 grep -H "foo"
Regular expression! Wanted to get some in here because it can be useful to filter the searched files.
find . -regex '.*/[a-z].txt' -print0 | xargs -0 grep -H "foo"
One thing to remember is that
find can use different regex dialects. On BSD OS’s (which macOS is a variation of) it by default uses the basic POSIX regular expression and the
+ doesn’t work there. So you need to enable the extended POSIX regular expression by adding the option
-E. Check out regexp types reference.
find -E . -regex '.*/[0-9]+.jpg'
The above should match all files like
9999999.jpg for that matter. The
+ should make the preceding expression match one or more times. It works everywhere! But not on mac 💩. There is no
-v or anything to see which version it is. It obviously comes from some
BSD version (
man find says
BSD General Commands Manual). But which is a mystery for me.
Get rid of annoying error output
When you’re not
root and search the whole filesystem you will for sure get a lot of permission denied output which can be overwhelming. There’s a trick to get rid of that:
find / -regex '.*/[0-9]+.jpg' 2>/dev/null
2 is the
Standard error file descriptor, i.e.,
stderr it will redirect all errors to
/dev/null which is a black hole where you never ever come back from if you get in 😱.
Read more about redirections of input/output here: http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection-1