特殊:Badtitle/NS100:Find:修订间差异

来自Ubuntu中文
跳到导航跳到搜索
Wikibot留言 | 贡献
无编辑摘要
Wikibot留言 | 贡献
无编辑摘要
 
第1行: 第1行:
{{From|https://help.ubuntu.com/community/find}}
{{From|https://help.ubuntu.com/community/find}}
{{Languages|UbuntuHelp:find}}
{{Languages|UbuntuHelp:find}}
<<Include(Tag/StyleCleanup)>>
== Introduction ==
<<Include(Tag/NeedsExpansion)>>
The GNU find command search files within within a directory and its subdirectories according to several criteria such as name, size and time of last read/write. By default find prints the name of the located files but it can also perform commands on these files.  
== What Is find? ==
The GNU find command is part of the [http://www.gnu.org/software/findutils/ GNU findutils] and is installed on every Ubuntu system. findutils is actually made up of 4 utilities:
The GNU find command search files within within a directory and its subdirectories according to several criteria such as name, size and time of last read/write. It performs actions on the files found, by default it prints the name of the files.
<ol><li>'''find''' - search for files in a directory hierarchy
The GNU find command is installed on every Ubuntu system. This page is complemented by the manual('man') page for find which can be read by issuing the command "man find".
</li><li>'''locate''' - list files in databases that match a pattern
(See [[UbuntuHelp:BasicCommands|BasicCommands]] for a quick introduction to the command line)
</li><li>'''updatedb''' - update a file name database
</li><li>'''xargs''' - build and execute command lines from standard input</li></ol>
 
This wiki page will be only be dealing with find while also briefly mentioning xargs. Hopefully locate and updatedb will be covered on their own page in the near future.
== The Basics ==
== The Basics ==
The general syntax for using finds is:
The syntax for using find is:
<pre><nowiki>
<pre><nowiki>
find [-H] [-L] [-P] [path...] [expression]</nowiki></pre>
find [-H] [-L] [-P] [path...] [expression]
We will ignore the options [-H] [-L] [-P] for now , please refer to man find to learn their meaning, and start with the [path...].
</nowiki></pre>
find search a directory and its subdirectories, before any expression you should specify the directory or the directories where find will start searching
The 3 options [-H] [-L] [-P] are not commonly seen but should at least be noted if only to realise that the -P option will be the ''default'' unless another option is specified:
* -H : Do  not  follow symbolic links, except while processing the command line arguments.
* -L : Follow symbolic links.
* -P : Never follow symbolic links: the default option.
The option [path...] refers to the particular location that you wish to search, whether it be your $HOME directory, a particular directory such as /usr, your present working directory which can simply be expressed as '.' or your entire computer which can be expressed as '/'.
The option [expression] refers to one or a series of options which effect the overall option of the find command. These options can involve a search by name, by size, by access time or can also involve actions taken upon these files.  
=== Locating Files by Name ===
The most common use of find is in the search for a specific file by use of its name. The following command searches the home directory and all of its subdirectories looking for the file mysong.ogg:
<pre><nowiki>
<pre><nowiki>
find . # search within the  current directory
find $HOME -name 'mysong.ogg'
find /home/user1 /home/user2  #search within the directories home/user1 /home/user2
</nowiki></pre>
find # same as find . , by default GNU find uses  the current directory if no path is specified</nowiki></pre>
It is important to get into the habit of quoting patterns in your search as seen above or your search results can be a little unpredictable. Such a search can be much more sophisticated though. For example if you wished to search for ''all'' of the ogg files in your home directory, some of which you think might be named 'OGG' rather than 'ogg', you would run:
The above commands will print the names of all the files present in the hierarchy below the starting directories passed to find as arguments. "files" can be link, directories, hidden files ...
== Searching Files With A Specific Name ==
Of course, find would just be a poor version of ls without the [expression] part, let's start by the most common and perhaps most simple example:
<pre><nowiki>
<pre><nowiki>
find dir -name 'myfile' </nowiki></pre>
find $HOME -iname '*.ogg'  
The  test -name 'name' will only search for an ''exact'' match of the name. This means that the above command
</nowiki></pre>
will find, in the directory dir, a file named "myfile" but not a file named "myfile.txt" or "thisismyfile". If you are looking for a file with "myfile" in the name somewhere, you should instead use the following:  
Here the option '-iname' performs a case-insensitive search while the wildcard character '*' matches any character, or number of characters, or zero characters. To perform the same search on your ''entire drive'' you would run:
<pre><nowiki>
<pre><nowiki>
find dir -name '*myfile*' </nowiki></pre>
sudo find / -iname '*.ogg'  
Here, the * is a wildcard, and can stand for any number of characters (number, letter, space...). It is a basic form of a pattern. See the find manual page for more on patterns. The most important thing here is:
</nowiki></pre>
'''Do not forget to put quotes around your pattern.'''
This could be a slow search depending on the number of directories, sub-directories and files on your system. This highlights an important difference in the way that find operates in that it examines the system ''directly'' each time unlike programs like locate or slocate which actually examine a regularly updated ''database'' of filnames and locations.
If the pattern is not quoted, it will be replace by the shell by the list of files matching the pattern in the current directory. For example, if your current directory contains the file mytestfile and the directory myfiles, and the myfiles directory that has the file test.txt.
=== Locating Files by Size ===
Another possible search is to search for files by ''size''. To demonstrate this we can again search the home directory for Ogg Vorbis files but this time looking for those that are 100 megabytes or larger:
<pre><nowiki>
<pre><nowiki>
$ ls
find $HOME -iname '*.ogg' -size +100M
myfiles  mytestfile
</nowiki></pre>
$ ls myfiles/
There are several options with -size, I have used 'M' for 'megabytes' here but 'k' for 'kilobytes' can be used or 'G' for 'Gigabytes'. This search can then be altered to look for ''files'' only that are ''less'' than 100 megabytes:
test.txt</nowiki></pre>
and we run the above find command
<pre><nowiki>
<pre><nowiki>
$ find . -name *test* #<-- wrong
find $HOME -iname '*.ogg' -type f -size -100M
./mytestfile</nowiki></pre>
</nowiki></pre>
Not exactly what we expected.  What has happened is the shell (Command Line Interface program) has interpreted ''*test*'' and matched it to ''mytestfile''.  ''mytestfile'' is what the shell passed as an argument to the find command.  We need to stop the shell interpreting ''*test*'' before passing it to ''find''.  We do this by putting single quotes (') around the pattern.
Are you starting to see the power of find, and the thought involved in constructing a focused search? If you are interested there is more discussion of these ''combined'' searches in the Advanced Usage section below.
You might have used an unquoted pattern before and it was working, this is because if the pattern doesn't match anything in the current directory the shell leaves the pattern unchanged. Of course it's better not to rely on what might or might not be in the current directory..
=== Locating Files by Access Time ===
== Searching Files With A Specific Size ==
It is also possible to locate files based on their access time or the time that they were last used, or viewed by the system. For example to show all files that have not been accessed in the $HOME directory for 30 days or more:
This parts needs expansion.
<pre><nowiki>
*-size: the size of the file such as : 600M for a 600 megabytes file. You can also specify a minimum size by adding a +  in front of the size. Like so: +600M will find files of 600 or more megabytes.
find $HOME -atime +30
== Acting On The files ==
</nowiki></pre>
This parts needs expansion.
This type of search is normally more useful when combined with ''other'' find searches. For example one could search for all ogg files in the $HOME directory that have an access time of greater than 30 days:
*-exec: This is used to execute a command to the filenames found. Use {} to substitute the filename and \; to end the command Ex: find ./ -name test.txt -exec ls -l {} \;
<pre><nowiki>
find $HOME -iname '*.ogg' -atime +30
</nowiki></pre>
The syntax works from left to right and by default find joins the 2 expressions with an implied "and". This is dealt with in more depth in the section below entitled "Combining Searches".
== Advanced Usage ==
== Advanced Usage ==
You can combine several Expressions, for instance if you want to find the files whose names  contains both "dylan" and ogg you can do:
The sections above detail the most common usage of find and this would be enough for most searches. However there are many more possibilities in the usage of find for quite advanced searches and this sections discusses a few of these possibilities.
=== Combining Searches ===
It is possible to combine searches when using find with the use of what is known in the find man pages as ''operators''. The classic example is the use of a logical AND syntax:
<pre><nowiki>
find $HOME -iname '*.ogg' -size +20M
</nowiki></pre>
This find search performs initially a case insensitive search for all the ogg files in your $HOME directory and for every true results it then searches for those with a size of 20 megabytes and over. This contains and implied operator which could be written joined with an ''-a''. This search can be altered slightly by use of an exclamation point to signify negation of the result:
<pre><nowiki>
<pre><nowiki>
find . -name '*dylan*' -name '*ogg*'</nowiki></pre>
find $HOME -iname '*.ogg' ! -size +20M
There is an implicit and between the arguments. If you want to find the files whose names contains "dylan" or "elvis" you can do:
</nowiki></pre>
This performs the same search as before but will look for ogg files that are ''not'' greater than 20 megabytes. It is possible also to use a logical OR in your find search:
<pre><nowiki>
<pre><nowiki>
find . -name '*dylan*' -o -name '*elvis*'</nowiki></pre>  
find $HOME -iname '*.ogg' -o -iname '*.mp3'
To search the files related to some specific user name you can do:
</nowiki></pre>
This will perform a case insensitive search in the $HOME directories and find all files that are either ogg OR mp3 files. There is great scope here for creating very complex and finely honed searches and I would encourage a through reading of the find man pages searching for the topic OPERATORS.
=== Acting On The files ===
One advanced but highly useful aspect of find usage is the ability to perform a user-specified action on the result of a find search. For example the following search looks for all ogg vorbis files in the $HOME directory and then uses -exec to pass the result to the du program to give the size of each file:
<pre><nowiki>
<pre><nowiki>
find . / -user "root"</nowiki></pre>
find $HOME -name '*.ogg' -type f -exec du -h '{}' \;
To search for files that are larger then a given size. The following will find all teh avi files under /home that are larger then 700M the following can used.
</nowiki></pre>
This syntax is often used to delete files by using ''-exec rm -rf'' but this must be used with great caution, if at all, as recovery of any deleted files can be quite difficult.
=== Using xargs ===
When using a really complex search it is often a good idea to use another member of the findutils package: xargs. Without its use the message ''Argument list too long'' could be seen signalling that the kernel limit on the combined length of a commandline and its environment variables has been exceeded. xargs works by feeding the results of the search to the subsequent command in batches calculated on the system capabilities (based on ARG_MAX). An example:
<pre><nowiki>
<pre><nowiki>
find /home -name '*.avi' -a size 700M </nowiki></pre>
find /tmp -iname '*.mp3' -print0 | xargs -0 rm
</nowiki></pre>
This example searches the /tmp folder for all mp3 files and then deletes them. You will note the use of both ''-print0'' and ''xargs -0'' which is a deliberate strategy to avoid problems with spaces and/or newlines in the filenames. Modern kernels do not have the ARG_MAX limitation but to keep your searches portable it is an excellent idea to use xargs in complex searches with subsequent commands.
== More Information ==
*[http://ubuntuforums.org/showthread.php?t=1128937 Linux Basics: A gentle introduction to 'find'] - An Ubuntu Forums guide that was incorporated into this wiki article with the gracious permission of its author.
*[http://mywiki.wooledge.org/UsingFind Using Find - Greg's Wiki] - A very comprehensive guide to using find, along similar lines to this guide, that is well worth reading through.
*[http://www.youtube.com/watch?v=x_R_JSiupzo Linux Tutorial: The Power of the Linux Find Command] The amazing Nixie Pixel gives a video demonstration of find.
----
----
[[category:CategoryCommandLine]]
[[category:CategoryCommandLine]]


[[category:UbuntuHelp]]
[[category:UbuntuHelp]]

2009年11月17日 (二) 19:07的最新版本

{{#ifexist: :Find/zh | | {{#ifexist: Find/zh | | {{#ifeq: {{#titleparts:Find|1|-1|}} | zh | | }} }} }} {{#ifeq: {{#titleparts:Find|1|-1|}} | zh | | }}

Introduction

The GNU find command search files within within a directory and its subdirectories according to several criteria such as name, size and time of last read/write. By default find prints the name of the located files but it can also perform commands on these files. The GNU find command is part of the GNU findutils and is installed on every Ubuntu system. findutils is actually made up of 4 utilities:

  1. find - search for files in a directory hierarchy
  2. locate - list files in databases that match a pattern
  3. updatedb - update a file name database
  4. xargs - build and execute command lines from standard input

This wiki page will be only be dealing with find while also briefly mentioning xargs. Hopefully locate and updatedb will be covered on their own page in the near future.

The Basics

The syntax for using find is:

find [-H] [-L] [-P] [path...] [expression]

The 3 options [-H] [-L] [-P] are not commonly seen but should at least be noted if only to realise that the -P option will be the default unless another option is specified:

  • -H : Do not follow symbolic links, except while processing the command line arguments.
  • -L : Follow symbolic links.
  • -P : Never follow symbolic links: the default option.

The option [path...] refers to the particular location that you wish to search, whether it be your $HOME directory, a particular directory such as /usr, your present working directory which can simply be expressed as '.' or your entire computer which can be expressed as '/'. The option [expression] refers to one or a series of options which effect the overall option of the find command. These options can involve a search by name, by size, by access time or can also involve actions taken upon these files.

Locating Files by Name

The most common use of find is in the search for a specific file by use of its name. The following command searches the home directory and all of its subdirectories looking for the file mysong.ogg:

find $HOME -name 'mysong.ogg' 

It is important to get into the habit of quoting patterns in your search as seen above or your search results can be a little unpredictable. Such a search can be much more sophisticated though. For example if you wished to search for all of the ogg files in your home directory, some of which you think might be named 'OGG' rather than 'ogg', you would run:

find $HOME -iname '*.ogg' 

Here the option '-iname' performs a case-insensitive search while the wildcard character '*' matches any character, or number of characters, or zero characters. To perform the same search on your entire drive you would run:

sudo find / -iname '*.ogg' 

This could be a slow search depending on the number of directories, sub-directories and files on your system. This highlights an important difference in the way that find operates in that it examines the system directly each time unlike programs like locate or slocate which actually examine a regularly updated database of filnames and locations.

Locating Files by Size

Another possible search is to search for files by size. To demonstrate this we can again search the home directory for Ogg Vorbis files but this time looking for those that are 100 megabytes or larger:

find $HOME -iname '*.ogg' -size +100M 

There are several options with -size, I have used 'M' for 'megabytes' here but 'k' for 'kilobytes' can be used or 'G' for 'Gigabytes'. This search can then be altered to look for files only that are less than 100 megabytes:

find $HOME -iname '*.ogg' -type f -size -100M 

Are you starting to see the power of find, and the thought involved in constructing a focused search? If you are interested there is more discussion of these combined searches in the Advanced Usage section below.

Locating Files by Access Time

It is also possible to locate files based on their access time or the time that they were last used, or viewed by the system. For example to show all files that have not been accessed in the $HOME directory for 30 days or more:

find $HOME -atime +30

This type of search is normally more useful when combined with other find searches. For example one could search for all ogg files in the $HOME directory that have an access time of greater than 30 days:

find $HOME -iname '*.ogg' -atime +30

The syntax works from left to right and by default find joins the 2 expressions with an implied "and". This is dealt with in more depth in the section below entitled "Combining Searches".

Advanced Usage

The sections above detail the most common usage of find and this would be enough for most searches. However there are many more possibilities in the usage of find for quite advanced searches and this sections discusses a few of these possibilities.

Combining Searches

It is possible to combine searches when using find with the use of what is known in the find man pages as operators. The classic example is the use of a logical AND syntax:

find $HOME -iname '*.ogg' -size +20M 

This find search performs initially a case insensitive search for all the ogg files in your $HOME directory and for every true results it then searches for those with a size of 20 megabytes and over. This contains and implied operator which could be written joined with an -a. This search can be altered slightly by use of an exclamation point to signify negation of the result:

find $HOME -iname '*.ogg' ! -size +20M 

This performs the same search as before but will look for ogg files that are not greater than 20 megabytes. It is possible also to use a logical OR in your find search:

find $HOME -iname '*.ogg' -o -iname '*.mp3'

This will perform a case insensitive search in the $HOME directories and find all files that are either ogg OR mp3 files. There is great scope here for creating very complex and finely honed searches and I would encourage a through reading of the find man pages searching for the topic OPERATORS.

Acting On The files

One advanced but highly useful aspect of find usage is the ability to perform a user-specified action on the result of a find search. For example the following search looks for all ogg vorbis files in the $HOME directory and then uses -exec to pass the result to the du program to give the size of each file:

find $HOME -name '*.ogg' -type f -exec du -h '{}' \;

This syntax is often used to delete files by using -exec rm -rf but this must be used with great caution, if at all, as recovery of any deleted files can be quite difficult.

Using xargs

When using a really complex search it is often a good idea to use another member of the findutils package: xargs. Without its use the message Argument list too long could be seen signalling that the kernel limit on the combined length of a commandline and its environment variables has been exceeded. xargs works by feeding the results of the search to the subsequent command in batches calculated on the system capabilities (based on ARG_MAX). An example:

find /tmp -iname '*.mp3' -print0 | xargs -0 rm

This example searches the /tmp folder for all mp3 files and then deletes them. You will note the use of both -print0 and xargs -0 which is a deliberate strategy to avoid problems with spaces and/or newlines in the filenames. Modern kernels do not have the ARG_MAX limitation but to keep your searches portable it is an excellent idea to use xargs in complex searches with subsequent commands.

More Information