Find Files and Folders with `find` in Bash

Cameron Nokes
InstructorCameron Nokes

Share this video with your friends

Send Tweet
Published 4 years ago
Updated 3 years ago

find is a powerful tool that can not only find files but it can run a command on each matching file too. In this lesson, we’ll learn how to find all the images that match a pattern and run an image optimization tool on them.

Instructor: [00:00] In my current working directory, I have an images folder. The images folder has several images in it, as you can see. Let's say that I wanted to find all of the PNGs in the folder. To do that, I would use the find command. I'll pass the images folder, and then I'll pass the name flag, and I'll do wildcard.png.

[00:20] This might look like a regex, but it's not, actually. This is just a string that supports some special characters that do matching, so this will match any file name that ends with .png.

[00:31] Let's run that. We can see it finds those two PNG files. If we do the same thing for JPGs, we can see it just returns that one, but we have two JPEGs in there.

[00:43] Instead of using name, we can use iname. The iname is a case-insensitive name search. If we run that now, we can see this one is returned, as well.

[00:53] Another useful one, for example, is if we do find. If I just wanted to find all folders in my current working directory, I would pass type D, and that'll return the images folder we just looked at.

[01:05] I have another folder in here called dist, so we can just confirm that with the list here. We can combine type with name. If I wanted to find all folders named images, that would work, and just returns the one here.

[01:21] Find also supports running an action on each match. For example, in my dist folder, I have two JS files, and then an image file.

[01:32] Let's say that I wanted to delete all the JS files from the dist folder. I'll do find dist. I'll do name, and I'll do wildcard.built.js, and then I'll pass the delete flag. If we list it out, now we can see that that had to lead in my two JavaScript files in there.

[01:51] If we want, we can get more custom, too. For example, if I wanted to run an image compression and optimization tool on each of the matching images, I could do that.

[02:00] I do find images. I'll do name, and I'll just run this on the PNGs. I'll pass the exec flag. That lets us run an arbitrary command on each match.

[02:11] I have a tool called pngquant that I have installed previously. Pngquant just optimizes PNG files and makes them smaller.

[02:19] Find supports this special character. The two curly braces stand further from each matching file.

[02:25] To end this little expression, you have to do your backslash, and then semicolon. Strange syntax, but if we run that, and then let's list out images, we can see that it worked. Pngquant, I've created these two optimized image files.

[02:40] Find's a really handy tool. Refer to the documentation on it for more possibilities. The easy way to look at the documentation is if you run man-find. Man stands for manual, and so this will bring up all of find's options right here in your terminal.

Vinícius Melo
Vinícius Melo
~ 3 years ago

Very Good Course... help me a lot in understand the linux bash/shell.

Pascal Chouinard
Pascal Chouinard
~ 3 years ago

I hate find ... I now use https://github.com/sharkdp/fd

Alex
Alex
~ 3 years ago

I am building a script that allows me to copy files (including a hashed js bundle) to a new folder. The filename is of the format bundle.[hash].js. Given that I want to do this every time I build the file (with a new hash), how can I find the file name so that I can use it in the cp command, without finding any other files that might be of the same format in child folders?

Cameron Nokes
Cameron Nokesinstructor
~ 3 years ago

how can I find the file name so that I can use it in the cp command, without finding any other files that might be of the same format in child folders?

find dist -name 'bundle.*.js' -maxdepth 1 -exec cp {} somewhere \;

Sounds like something like that would work. You can use the -maxdepth option to prevent find from searching deeper than you want it to. Hopefully that works for you!