Linux delete file with size 0 [duplicate]
Not suitable for this site 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.
How do I delete a certain file in linux if its size is 0. I want to execute this in an crontab without any extra script.
l filename.file | grep 5th-tab | not eq 0 | rm
8 Answers 8
This will delete all the files in a directory (and below) that are size zero.
find /tmp -size 0 -print -delete
If you just want a particular file;
if [ ! -s /tmp/foo ] ; then rm /tmp/foo fi
shortcut: [ -s /tmp/foo ] || rm /tmp/foo (test if size is zero, else remove). Also note the xargs is unsafe if file/directory names contain spaces; find . -exec rm ‘<>‘ \; is safe in that situation.
@FrankH: Plus, even if using find -exec , always favour + over ; in cases where you can (and this is one such case).
Would rm — (note the trailing — characters) be safer here than simply rm to prevent rogue filenames? serverfault.com/questions/337082/…
@lilydjwg Exactly, if we’re allowed to use non POSIX flags, find . -empty -delete is the coolest. 🙂
To search and delete empty files in the current directory and subdirectories:
find . -type f -empty -delete
-type f is necessary because also directories are marked to be of size zero.
The dot . (current directory) is the starting search directory. If you have GNU find (e.g. not Mac OS), you can omit it in this case:
If no files to search are specified, the current directory (.) is used.
I would add -name ‘*.SomeFileExtension’ for example: if you wanted to delete just text files then I would use: find . -name ‘*.txt’ -type f -empty -delete
@jspek, well, that depends if you have that specific use. Usually when you are after empty files you are up to kill them all. 🙂
Had to grab a coffee after running this command on a directory with 2.2 million files. 😛 Had worked like a charm when I came back, 350.000 remained. Thanks!
You can use the command find to do this. We can match files with -type f , and match empty files using -size 0 . Then we can delete the matches with -delete .
find . -type f -size 0 -delete
find . -maxdepth 1 -type f -size 0 -delete This finds the empthy files in the current directory without going into sub-directories.
On Linux, the stat(1) command is useful when you don’t need find(1):
(( $(stat -c %s "$filename") )) || rm "$filename"
The stat command here allows us just to get the file size, that’s the -c %s (see the man pages for other formats). I am running the stat program and capturing its output, that’s the $( ) . This output is seen numerically, that’s the outer (( )) . If zero is given for the size, that is FALSE, so the second part of the OR is executed. Non-zero (non-empty file) will be TRUE, so the rm will not be executed.
How do I delete all files smaller than a certain size in all subfolders?
I have a folder with many sub-folders containing small tif files (less than 160kb) which have been merged together in bigger pdf files, together with some big multi-page tif files. I want to delete all small tif files without deleting the bigger files (tif or pdf) and retaining the directory structure. How do I go about it on Linux using the command-line?
1 Answer 1
find . -type f -name "*.tif" -size -160k -delete
This will search for files with filenames matching the glob *.tif and size smaller than 160 kilobytes recursively (in the current directory and all subdirectories) 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.
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).
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 .
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, for all but the simplest find commands, you will want to filter only files or only 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).
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.
Удаляем файлы определенного размера и дубликаты
К написанию этой статьи меня подвигли постоянные восстановления данных с «флешек» или карт памяти. После спасения данных (изображений, музыки, документов и т.д.) программами Photores и Foremost, в каталоге с найденными файлами появляется много картинок маленького размера и много дубликатов. Поэтому раньше очень много времени я тратил на сортировку файлов по размеру и удалял файлы небольшого размера. Но Linux потому и Linux, что может решить множество нужных задач при помощи нескольких команд в Терминале. Быстро и эффективно!
Как правило программы для восстановления запускаются от супер пользователя, поэтому просто так удалить восстановленные файлы мы не сможем. Для этого я изменяю владельца для этих каталогов и становлюсь их хозяином. После этого нужные файлы и каталоги удаляются от обычного пользователя без проблем. Итак, меняем владельца каталога:
sudo chown -R user:user ~/Recovery
user — Ваш логин в системе
~/Recovery — каталог с восстановленными файлами. В Вашем случае он скорее всего будет другой.
После этого нам нужно удалить картинки маленького размера. Размер напишите свой, потому что в одном случае нужное изображение может быть от 2 Мб и выше, а в другом случае размер может быть от 300Кб, если фото делалось в телефоне среднего качества. Поэтому я установлю размер удаляемых картинок меньше 60 кб:
find ~/Recovery -type f -size -60k -exec rm <> \;
В данном случае производится поиск в каталоге ~/Recovery. Параметр -type f указывает программе, что нужно искать именно файлы, а не каталоги, а команда rm удалит все файлы, которые ниже размера, указанного в параметре -size -60k . Если нужно в будущем удалять и каталоги, то добавьте параметр -type d .
После этого мне нужно было удалить и дубликаты, которые появились после восстановления. Это делается при помощи утилиты fdupes. Если не установлена, то выполним команду в Терминале:
sudo apt-get install fdupes
А теперь удалим ненужные дубликаты командой:
-r — рекурсивный поиск в каталоге;
-d — параметр для удаления;
-N — данный параметр поможет удалить каждый файл без постоянного переспрашивания и ожидания Вашей реакции;
~/Recovery — каталог с дубликатами.
После этих команд в каталоге остались практически все нужные фотографии и другие файлы.
p.s. Все больше и больше влюбляюсь в этот безумный и обалденный LINUX!