- Find images in a Linux directory based on their resolution
- 1 Answer 1
- How to Search for Files from the Linux Command Line
- What is the find command in Linux?
- Examples of the find command
- How to search files by name or extension
- How to search hidden files
- How to search log files and configuration files
- How to search other files by type
- How to search directories
- How to search files by size
- Practical examples of find with bash scripts
- Wrapping up
- List all graphic image files with find? [closed]
- 6 Answers 6
- Update (2022-03-03)
Find images in a Linux directory based on their resolution
I would like to scan all images in a directory (recursively within sub-folders), and find those with resolution higher than a specific threshold (e.g. say those with resolutions at least 800×600 or if easier, say with width higher than 1000 pixels). Then I would like to log their address in a text file, accompanying their resolution (or [width], [height] for a better formatting). So log.txt would look like this:
/home/users/myuser/test/image1.jpg, 1800, 1600 /home/users/myuser/test/image20.jpg, 2800, 2600 /home/users/myuser/test/image30.jpg, 1500, 1200
1 Answer 1
Via bash’s recursive glob and ImageMagick’s identify command:
shopt -s globstar identify -format "%f, %w, %h\n" **/*.
Saving such output to file , is just a matter of adding > mylog.txt to previous command, that is
identify -format "%f, %w, %h\n" **/*. > mylog.txt
From there, you could use awk or perl to compare mylog.txt columns
awk -F ',' '$2 > 800 && $3 > 600' mylog.txt
awk here uses , as separator for columns, and the usual structure for awk is /PATTERN/ , which defaults to just printing if omitted ; in the particular example above, if the pattern $2 > 800 && $3 > 600 is true, that is it’s the image above desired resolution, you’ll get it printed to the screen.
And probably skipping the log step in between, it would be a little better to just pipe everything:
shopt -s globstar identify -format "%f, %w, %h\n" **/*. | awk -F ',' '$2 > 800 && $3 > 600' > filtered_images.txt
In case you encounter arguments list too long error, typically find command is better approach for recursively walking the directory tree. The identify can be called through find ‘s -exec flag, and filtering still can be handled by awk :
$ find -type f -regex "^.*\.\(png\|jpg\|jpeg\)$" -exec identify -format "%f, %w, %h\n" <> \; | awk -F ',' '$2 > 800 && $3 > 600' fanart.jpg, 1920, 1080 fanart.jpg, 1920, 1080 globalsearch-background.jpg, 1920, 1080 fanart.jpg, 1280, 720
As usual, don’t forget to add > log2.txt to save everything to file.
Full path of to the file could be handled in either one of two ways. One, by specifying %d/%f in identify command’s format string, or use find ‘s -printf option. That is either
find -type f -regex "^.*\.\(png\|jpg\|jpeg\)$" -exec identify -format "%d/%f, %w, %h\n" <> \; | awk -F ',' '$2 > 800 && $3 > 600'
find -type f -regex "^.*\.\(png\|jpg\|jpeg\)$" -printf "%p, " -exec identify -format "%w, %h\n" <> \; | awk -F ',' '$2 > 800 && $3 > 600'
How to Search for Files from the Linux Command Line
Zaira Hira
Searching for files is relatively easy when you are using a GUI. But in certain environments like GUI-less servers, you need to search for files using the command line.
There is a powerful command in Linux that helps you search for files and folders called find . In this article, we will discuss the find command with some examples.
What is the find command in Linux?
The find command lets you efficiently search for files, folders, and character and block devices.
Below is the basic syntax of the find command:
find /path/ -type f -name file-to-search
- /path is the path where file is expected to be found. This is the starting point to search files. The path can also be / or . which represent root and current directory, respectively.
- -type represents the file descriptors. They can be any of the below:
f – Regular file such as text files, images and hidden files.
d – Directory. These are the folders under consideration.
l – Symbolic link. Symbolic links point to files and are similar to shortcuts.
c – Character devices. Files that are used to access character devices are called character device files. Drivers communicate with character devices by sending and receiving single characters (bytes, octets). Examples include keyboards, sound cards and mouse.
b – Block devices. Files that are used to access block devices are called block device files. Drivers communicate with block devices by sending and receiving entire blocks of data. Examples include USB, CD-ROM
Examples of the find command
Now we know the syntax of the find command, let’s look at some examples.
How to search files by name or extension
Suppose we need to find files that contain «style» in their name. We’ll use this command:
Now let’s say we want to find files with a particular extension like .html . We’ll modify the command like this:
How to search hidden files
Hidden files are represented by a dot in the beginning of the filename. They are normally hidden, but can be viewed with ls -a in the current directory.
We can modify the find command as shown below to search for hidden files.
How to search log files and configuration files
Log files usually have the extension .log , and we can find them like this:
Similarly, we can search for configuration files like this:
How to search other files by type
We can search for character block files by providing c to -type :
Similarly, device block files can be found by using b :
How to search directories
In the example below, we are finding the folders named lib . Note that we are using -type d .
💡 Tip: we can identify directories by looking at the d flag in the output of ls -lrt .
How to search files by size
An incredibly helpful use of the find command is to list files based on a particular size.
Let’s apply an example in my home directory.
find . -type f -name ".*" -mtime +10
Practical examples of find with bash scripts
We can combine find with rm or mv to create meaningful bash scripts that can be automated.
Let’s say we want to create a script that moves log files older than 7 days to a backup path. From there, it deletes log files older that older than 30 days. We can create a script and schedule it with cron . You can learn more about cron jobs here.
#!/bin/bash # Script to move from logs older than 7 days to backup logs path: /app/backup_logs/ESB0* # move ESB01 logs to backup find /logs/esb01/audit -name "*.tar.gz" -mtime +7 -exec mv <> app/backup_logs/ESB01/ \; # Remove logs from backup path after 30 days find /app/backup_logs/ESB01 -name "*.tar.gz" -mtime +30 -exec rm <> \;
Note that we are using exec with find . Basically, exec executes the command provided ( mv and rm in our case). <> is the placeholder which holds the results of the command. Lastly, we provide the delimiter ; . As we do not want the shell to interpret the semicolon, we escape it with \ .
The shared script is very useful in archiving and removing logs.
Wrapping up
In this article, we have studied the find command in detail and learned how to search files by name, type, size and modification time.
I hope you found this tutorial helpful.
You can read my other posts here.
Resources: Banner images from Office illustrations by Storyset and Canva.
List all graphic image files with find? [closed]
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
There are many types of graphic images in this huge archive such as .jpg, .gif, .png, etc. I don’t know all the types. Is there a way with ‘find’ to be able to have it list all the graphic images regardless of their dot extension name? Thanks!
For videos, see the corresponding Q&A here: Ask Ubuntu: How can I find all video files on my system?. For anyone wanting to add a new answer for images, you could probably just add it there as well.
6 Answers 6
find . -name '*' -exec file <> \; | grep -o -P '^.+: \w+ image'
./navigation/doc/Sphärische_Trigonometrie-Dateien/bfc9bd9372f650fd158992cf5948debe.png: PNG image ./navigation/doc/Sphärische_Trigonometrie-Dateien/6564ce3c5b95ded313b84fa918b32776.png: PNG image ./navigation/doc/subr_1.jpe: JPEG image ./navigation/doc/Astroanalytisch-Dateien/Gamma.gif: GIF image ./navigation/doc/Astroanalytisch-Dateien/deltaS.jpg: JPEG image ./navigation/doc/Astroanalytisch-Dateien/GammaBau.jpg: JPEG image
Is there a similar approach that can be taken for video? It seems that replacing «image» with «video» skips quicktime and Matroska formats.
@ElderGeek I would run file on some examples and see if there was a piece of text I could grep for. In the image section of the awk solution you could separate patterns with alternation for example /video|image|foo/ would return all files that had the word video, image, or foo in their description from file.
Any ideas on how I can get rid of the : GIF image or : JPEG image and just be left off with the name of the file plus the path so I can pass it to another command as an output?
Note that the \w+ part would exclude results like foo.svg: SVG Scalable Vector Graphics image . To find for example .svg files, change \w+ to .*
For macOS mojave, grep has no -P option, and the output of the file command is very verbose. By the way, it will be better if you could explain your command.
The following suits me better since in my case I wanted to pipe this list of files to another program.
find . -type f -exec file --mime-type <> \+ | awk -F: ''
If you wanted to tar the images up (as someone in the comments) asked
find . -type f -exec file --mime-type <> \+ | awk -F: '' | tar -cvf /tmp/file.tar --null -T -
The first oneliner leverages the following commands, find, file, and awk. The second oneliner adds tar. Your best bet is to consult your local man pages for the behavior of your specific system.
before using this command to create tar make sure you have enough free space! (in this case on root partition)
find . -type f -exec file <> \; | grep -o -P '^.+: \w+ image'
@Selah This command specifies -type f , which would get files but not folders and execute the file command, so it could be a bit quicker than j.holetzeck’s answer.
This command has issue if filename matched ^.+: \w+ image , e.g. hello: fake image . Consider this solution: find . -type f -print0 | xargs -0 bash -c ‘for arg do file -b —mime-type «$arg» | grep -q ‘^image/’ && echo «$arg»; done’ _ . Explanation: 1. file -b output only filetype to avoid filename match ^.+: \w+ image . 2. -print0 | xargs -0 able deal with newline in filename while my other comments not deal with that exotic case. 3. for loop with trailing _ to covers ‘ or $var in filename) 4. —mime-type avoid .psd («I»mage) and .eps (no «image») file type issues.
Grepping or using awk for «image» only will not do it. PSD-files will be identified by «Image» with a capital «I» so we need to improve the regexp to either be case insensitive or also include the capital I. EPS-files will not contain the word «image» at all so we need to also match for «EPS» or «Postscript» depending on what you want. So here is my improved version:
find . -type f -exec file <> \; | awk -F: '< if ($2 ~/[Ii]mage|EPS/) print $1>'
Update (2022-03-03)
This is a refined version with the following changes:
find . -type f | file --mime-type -f - | grep -F image/ | rev | cut -d : -f 2- | rev
Below is a more performant solution compared to the chosen answer:
find . -type f -print0 | xargs -0 file --mime-type | grep -F 'image/' | cut -d ':' -f 1
- Use -type f instead of -name ‘*’ since the former will search only files while the latter search both files and directories.
- xargs execute file with arguments as many as possible, which is super fast compared to find -exec file <> \; which executes file for each found.
- grep -F is faster since we only want to match fixed string.
- cut is faster than awk (more than 5 times faster as I can recall).
According to my limited testing my updated invocation executes faster than what you have currently, but I welcome the comments. Your use of xargs reminded me that find does something equivalent. Also the mime-types option to find is a good addition. It does produce a different results from what I had previously, but the biggest plus is it excludes virtual machine images. For an accurate comparison with awk you will need to combine grep piped in to cut since that is doing both of those things. Still awk will provide you more versatility. Thank you.
Should change cut -d ‘:’ -f 1 to rev | cut -d ‘:’ -f 2- | rev to print full filename contains : . e.g. hello : world.jpg