find . -type f -name "*.tif" -size -160k -delete
This will search recursively (in the current directory and all subdirectories) for files with filenames matching the glob *.tif
and size smaller than 160 kilobytes and then delete them.
Run the command without -delete
first. It will just list the files instead of deleting. This way you can verify the correct files are to be deleted.
Explanation:
A typical find command looks like this
find dirname -test a -test b -action
we start with all files (and all directories) in dirname
. then the tests filter the files (and directories) based on some criteria. the tests work in series. so the second test gets the result from the first test. the action then does things with the final result. if no explicit action is given then it is default -print
(print the filename including path to file).
in our case:
find . -type f -name "*.tif" -size -160k -delete
we start in current directory (the dot: .
); filter out directories (-type f
); filter by name; filter by size; and ultimately delete those files.
now explanation for each part. for brevity will i will only say "files" from now on instead of "files and directories".
find . -type f -name "*.tif" -size -160k -delete
^^^^^^^
This is the action. As the name says it instructs find to delete the files found.
A directory will only be deleted if it is empty. In our case it does not matter because we filtered out directories.
Other common actions are -printf
(to print based on custom format) or -exec
(to execute a command on the found file). There is also -ls
which will print the files found in a format similar to the command ls
.
As mentioned above: if you leave out the action then the default action is -print
find . -type f -name "*.tif" -size -160k -delete
^^^^^^^^^^^
This test filters the files based on size. This is the relevant part for this question.
Note the -
before 160k
. Just 160k
means exactly 160 kilobytes. -160k
means smaller than 160 kilobytes. +160k
means larger than 160 kilobytes.
If you want smaller and equal to 160k then do -161k
.
If you want to filter size in bytes (as in 160 bytes instead of 160 kilobytes) then you have to write it like this: 160c
. If you just write 160
it will be interpreted as 160*512 bytes. This is a strange requirement by POSIX. Read here for more details: https://unix.stackexchange.com/questions/259208/purpose-of-find-commands-default-size-unit-512-bytes
find . -type f -name "*.tif" -size -160k -delete
^^^^^^^^^^^^^
This test filters the files based on filename.
The pattern is a glob. It works like you would expect in a typical command like for example rm *.tif
.
Be carefull to put the glob in quotes ("*.tif"
). Otherwise the shell will expand the glob before find gets the arguments and it will execute a completely different command. See here for more information about quoting the glob: https://unix.stackexchange.com/questions/82139/what-is-the-difference-between-pl-and-pl-in-grep-why-does-quoting-change
There are several tests that filter agains the "name" of a file: -name
matches against the filename regardless of the path to the file. -path
matches against the filename and the path to the file. and -regex
which uses regular expression instead of glob to match against filename including path.
for more info on glob and regex read this article https://www.linuxjournal.com/content/globbing-and-regex-so-similar-so-different or search for "difference glob regex"
find . -type f -name "*.tif" -size -160k -delete
^^^^^^^
This test filters based on type. In this case we request it to only filter for files.
If you leave this test out you get both files and directories.
Typically you will want to filter only files or only directories as many filters and actions only make sense on files or directories.
To filter only directories use -type d
.
find . -type f -name "*.tif" -size -160k -delete
^
the dot (.
) stands for the current directory. you can also search another directory in the current directory
find some/dir -type f -name "*.tif" -size -160k -delete
or an absolute path somewhere on the system
find /absolute/path -type f -name "*.tif" -size -160k -delete
on sane versions of find (GNU find) you can leave out the dot and it will search in the current directory by default. practically all linuxes use the GNU version of find. some overpriced non-free systems (Mac OS X) use outdated and/or inferior versions of find just to avoid the GPL (the perpetualy free license of GNU and linux).
see here for more info on apple avoiding GPL: http://meta.ath0.com/2012/02/05/apples-great-gpl-purge/
bonus!
if you want to exclude subfolders, or in other words: not recursively, then do it like this
find . -maxdepth 1 -type f -name "*.tif" -size -160k -delete
^^^^^^^^^^^
this will tell find to not look deeper than one level. in effect it will not go down subdirectories.