- How do I get the find command to print out the file size with the file name?
- Find Command in Linux (Find Files and Directories)
- find Command Syntax #
- Find Files by Name #
- Find Files by Extension #
- Find Files by Type #
- Find Files by Size #
- Find Files by Modification Date #
- Find Files by Permissions #
- Find Files by Owner #
- Find and Delete Files #
- Conclusion #
- How do I find files and total their sizes?
- 5 Answers 5
- Solution
- Explanation
How do I get the find command to print out the file size with the file name?
This version will exec «ls» process for each file. If you have many files (say, over a thousand) you better optimize that by either: find . -name ‘*.ear’ -exec ls -lh <> + \; (GNU extension) or find . -name ‘*.ear’ -print0 | xargs -0 ls -lh . Also you may like to add -type f if you’re only interested in files (or add -d to ls if you want directories themselves included without their contents).
Your answer does not exclude directories, so you will end up running ls on directories as well, which clearly is not the right thing to do.
This is a really inefficient way of doing things — and unfortunately ash108’s comments are also not ideal. It’s much better to use the -printf option to find.
dmazzoni’s answer is much more efficient because it avoids a fork+exec on every file (100x faster on my machine). I had to change %k to %s. @FaheemMitha: you can add options like -type f to only count regular files.
You need to use -exec or -printf. Printf works like this:
find . -name *.ear -printf "%p %k KB\n"
-exec is more powerful and lets you execute arbitrary commands — so you could use a version of ‘ls’ or ‘wc’ to print out the filename along with other information. ‘man find’ will show you the available arguments to printf, which can do a lot more than just filesize.
[edit] -printf is not in the official POSIX standard, so check if it is supported on your version. However, most modern systems will use GNU find or a similarly extended version, so there is a good chance it will be implemented.
It looks like your example is more precise, but I can’t seem to get the example to work on Solaris 10.
I’m afraid Solaris find does not support -printf at all: jrwren.wrenfam.com/blog/2006/10/07/solaris-find-sucks cs.bgu.ac.il/~arik/usail/man/solaris/find.1.html You could install GNU find if you can be bothered, otherwise you need to use exec or | as suggested by others.
+1 This seems more cleaner. To format the output I would prefer add column command. find . -name *.ear -printf «%p %k KB\n» | column -t
A simple solution is to use the -ls option in find:
That gives you each entry in the normal «ls -l» format. Or, to get the specific output you seem to be looking for, this:
find . -name \*.ear -printf "%p\t%k KB\n"
Which will give you the filename followed by the size in KB.
Using GNU find, I think this is what you want. It finds all real files and not directories (-type f), and for each one prints the filename (%p), a tab (\t), the size in kilobytes (%k), the suffix » KB», and then a newline (\n).
find . -type f -printf '%p\t%k KB\n'
If the printf command doesn’t format things the way you want, you can use exec, followed by the command you want to execute on each file. Use <> for the filename, and terminate the command with a semicolon (;). On most shells, all three of those characters should be escaped with a backslash.
Here’s a simple solution that finds and prints them out using «ls -lh», which will show you the size in human-readable form (k for kilobytes and M for megabytes):
As yet another alternative, «wc -c» will print the number of characters (bytes) in the file:
Find Command in Linux (Find Files and Directories)
The find command is one of the most powerful tools in the Linux system administrators arsenal. It searches for files and directories in a directory hierarchy based on a user given expression and can perform user-specified action on each matched file.
You can use the find command to search for files and directories based on their permissions, type, date, ownership, size, and more. It can also be combined with other tools such as grep or sed .
find Command Syntax #
The general syntax for the find command is as follows:
find [options] [path. ] [expression]
- The options attribute controls the treatment of the symbolic links, debugging options, and optimization method.
- The path. attribute defines the starting directory or directories where find will search the files.
- The expression attribute is made up of options, search patterns, and actions separated by operators.
To search for files in a directory, the user invoking the find command needs to have read permissions on that directory.
Let’s take a look at the following example:
- The option -L (options) tells the find command to follow symbolic links.
- The /var/www (path…) specifies the directory that will be searched.
- The (expression) -name «*.js tells find to search files ending with .js (JavaScript files).
Find Files by Name #
Finding files by name is probably the most common use of the find command. To find a file by its name, use the -name option followed by the name of the file you are searching for.
For example, to search for a file named document.pdf in the /home/linuxize directory, you would use the following command:
find /home/linuxize -type f -name document.pdf
To run a case-insensitive search, change the -name option with -iname :
find /home/linuxize -type f -iname document.pdf
The command above will match “Document.pdf”, “DOCUMENT.pdf” ..etc.
Find Files by Extension #
Searching for files by extension is the same as searching for files by name. For example, to find all files ending with .log.gz inside the /var/log/nginx directory, you would type:
find /var/log/nginx -type f -name '*.log.gz'
It is important to mention that you must either quote the pattern or escape the asterisk * symbol with backslash \ so that it doesn’t get interpreted by the shell when you use the wildcard character.
To find all files that don’t match the regex *.log.gz you can use the -not option. For example, to find all files that don’t end in *.log.gz you would use:
find /var/log/nginx -type f -not -name '*.log.gz'
Find Files by Type #
Sometimes you might need to search for specific file types such as regular files, directories, or symlinks. In Linux, everything is a file.
To search for files based on their type, use the -type option and one of the following descriptors to specify the file type:
- f : a regular file
- d : directory
- l : symbolic link
- c : character devices
- b : block devices
- p : named pipe (FIFO)
- s : socket
For instance, to find all directories in the current working directory , you would use:
The common example would be to recursively change the website file permissions to 644 and directory permissions to 755 using the chmod command:
find /var/www/my_website -type d -exec chmod 0755 <> \;
find /var/www/my_website -type f -exec chmod 0644 <> \;
Find Files by Size #
To find files based on the file size, pass the -size parameter along with the size criteria. You can use the following suffixes to specify the file size:
- b : 512-byte blocks (default)
- c : bytes
- w : two-byte words
- k : Kilobytes
- M : Megabytes
- G : Gigabytes
The following command will find all files of exactly 1024 bytes inside the /tmp directory:
find /tmp -type f -size 1024c
The find command also allows you to search for files that are greater or less than a specified size.
In the following example, we search for all files less than 1MB inside the current working directory. Notice the minus — symbol before the size value:
If you want to search for files with a size greater than 1MB , then you need to use the plus + symbol:
You can even search for files within a size range. The following command will find all files between 1 and 2MB :
find . -type f -size +1M -size 21M
Find Files by Modification Date #
The find command can also search for files based on their last modification, access, or change time.
Same as when searching by size, use the plus and minus symbols for “greater than” or “less than”.
Let’s say that a few days ago, you modified one of the dovecot configuration files, but you forgot which one. You can easily filter all files under the /etc/dovecot/conf.d directory that ends with .conf and has been modified in the last five days:
find /etc/dovecot/conf.d -name "*.conf" -mtime 5
Here is another example of filtering files based on the modification date using the -daystart option. The command below will list all files in the /home directory that were modified 30 or more days ago:
find /home -mtime +30 -daystart
Find Files by Permissions #
The -perm option allows you to search for files based on the file permissions.
For example, to find all files with permissions of exactly 775 inside the /var/www/html directory, you would use:
You can prefix the numeric mode with minus — or slash / .
When slash / is used as the prefix, then at least one category (user, group, or others) must have at least the respective bits set for a file to match.
Consider the following example command:
The above command will match all the files with read permissions set for either user, group, or others.
If minus — is used as the prefix, then for the file to match, at least the specified bits must be set. The following command will search for files that have read and write permission for the owner and group and are readable by other users:
Find Files by Owner #
To find files owned by a particular user or group, use the -user and -group options.
For example, to search for all files and directories owned by the user linuxize , you would run:
Here is a real-world example. Let’s say you want to find all files owned by the user www-data and change the ownership of the matched files from www-data to nginx :
find / -user www-data -type f -exec chown nginx <> \;
Find and Delete Files #
To delete all matching files, append the -delete option to the end of the match expression.
Ensure you are using this option only when you are confident that the result matches the files you want to delete. It is always a good idea to print the matched files before using the -delete option.
For example, to delete all files ending with .temp from the /var/log/ , you would use:
find /var/log/ -name `*.temp` -delete
Use the -delete option with extreme caution. The find command is evaluated as an expression and if you add the -delete option first, the command will delete everything below the starting points you specified.
When it comes to directories, find can delete only empty directories, same as rmdir .
Conclusion #
We have shown you how to use the find command with various options and criteria.
This article should give you a fundamental understanding of how to locate files on your Linux systems. You may also visit the find man page and read about all other powerful options of the find command.
If you have any questions or remarks, please leave a comment below.
How do I find files and total their sizes?
I’d like to find a series of files (based on a wildcard expression) and total their disk usage. Something like this:
$ find . -name 'flibble*' -ctime +90 -exec du -sh <> \; 2.1G ./flibble_116.log 2.1G ./flibble_83.log 2.1G ./flibble_211040_157.log 2.1G ./flibble3747_51.log
This work. But it doesn’t produce the result I’m looking for. It lists the space used by each file, as find is iterating through them. What I want is the total du for all of the files found.
5 Answers 5
Solution
By supplying the option -c (or —total ) to du(1) , you can instruct it to produce a grand total. If your implementation of du(1) supports either of these options, you can achieve the desired effect using the following command:
$ find . -name 'flibble*' -ctime +90 -exec du -shc <> +
EDIT: Note that if the number of files exceeds the maximum number of parameters permitted by your system, find may still execute command multiple times. Some implementations of du(1) also support reading the filenames from a file, which does not suffer from the mentioned limitation:
$ find -name 'flibble*' -ctime +90 -print0 > filenames $ du -shc --files0-from=filenames
Explanation
The difference between the semantics of -exec command <> \; and -exec command <> + is the following:
- command <> \; executes command once for each result of find . The pathname of the result is passed instead of <> .
$ touch 1 2 3 $ find 1 2 3 -maxdepth 0 -exec echo <> \; 1 2 3
$ touch 1 2 3 $ find 1 2 3 -maxdepth 0 -exec echo <> + 1 2 3
The -print0 option causes find(1) to print the found filenames to the standard output separated by the null character, and the —files0-from option caused du(1) to read the null-separated filenames. Unlike the new line character, the null character may not appear in a filename, so the output is unambiguous.
To learn more about the options of du(1) and find(1) , you should consult the respective manpages: