在这Linux命令find&xargs详述

时间:2008-03-22 13:57:13  类别:linux命令  作者:kevin

find使用 来源于 man

-name

按照文件名查找文件。

-perm

按照文件权限来查找文件。

-prune

使用这一选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。

-user

按照文件属主来查找文件。

-group

按照文件所属的组来查找文件。

-mtime -n +n

按照文件的更改时间来查找文件, - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。

-nogroup

查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。

-nouser

查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。

-newer file1 ! file2

查找更改时间比文件file1新但比文件file2旧的文件。

-type

查找某一类型的文件,诸如:

b - 块设备文件。

d - 目录。

c - 字符设备文件。

p - 管道文件。

l - 符号链接文件。

f - 普通文件。

-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。

-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。

-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。

-mount:在查找文件时不跨越文件系统mount点。

-follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。

-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。

另外,下面三个的区别:

-amin n

  查找系统中最后N分钟访问的文件

  -atime n

  查找系统中最后n*24小时访问的文件

  -cmin n

  查找系统中最后N分钟被改变文件状态的文件

  -ctime n

  查找系统中最后n*24小时被改变文件状态的文件

-mmin n

  查找系统中最后N分钟被改变文件数据的文件

  -mtime n

  查找系统中最后n*24小时被改变文件数据的文件

examples

find /tmp -name core -type f -print | xargs /bin/rm -f

find /tmp -name core -type f -print0 | xargs -0 /bin/rm -f
find . -type f -exec file '{}' \;

find / \( -perm -4000 -fprintf /root/suid.txt '%#m %u %p\n' \) , \
\( -size +100M -fprintf /root/big.txt '%-10s %p\n' \)

Traverse the filesystem just once, listing setuid files and directories
into /root/suid.txt and large files into /root/big.txt.

find $HOME -mtime 0

find . -perm 664

Search for files which have read and write permission for their owner,
and group, but which other users can read but not write to. Files
which meet these criteria but have other permissions bits set (for
example if someone can execute the file) will not be matched.

find . -perm -664

Search for files which have read and write permission for their owner
and group, and which other users can read, without regard to the pres-
ence of any extra permission bits (for example the executable bit).
This will match a file which has mode 0777, for example.

find . -perm /222

Search for files which are writable by somebody (their owner, or their
group, or anybody else).

使用exec或ok来执行shell命令

使用find时,只要把想要的操作写在一个文件里,就可以用exec来配合find查找,很方便的

在有些操作系统中只允许-exec选项执行诸如l s或ls -l这样的命令。大多数用户使用这一选项是为了查找旧文件并删除它们。建议在真正执行rm命令删除文件之前,最好先用ls命令看一下,确认它们是所要删除的文件。

exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{ },一个空格和一个\,最后是一个分号。为了使用exec选项,必须要同时使用print选项。如果验证一下find命令,会发现该命令只输出从当前路径起的相对路径及文件名。

例如:为了用ls -l命令列出所匹配到的文件,可以把ls -l命令放在find命令的-exec选项中

# find . -type f -exec ls -l { } \;

-rw-r--r-- 1 root root 34928 2003-02-25 ./conf/httpd.conf

-rw-r--r-- 1 root root 12959 2003-02-25 ./conf/magic

-rw-r--r-- 1 root root 180 2003-02-25 ./conf.d/README

上面的例子中,find命令匹配到了当前目录下的所有普通文件,并在-exec选项中使用ls -l命令将它们列出。

在/logs目录中查找更改时间在5日以前的文件并删除它们:

$ find logs -type f -mtime +5 -exec rm { } \;

记住:在shell中用任何方式删除文件之前,应当先查看相应的文件,一定要小心!当使用诸如mv或rm命令时,可以使用-exec选项的安全模式。它将在对每个匹配到的文件进行操作之前提示你。

在下面的例子中, find命令在当前目录中查找所有文件名以.LOG结尾、更改时间在5日以上的文件,并删除它们,只不过在删除之前先给出提示。

$ find . -name "*.conf" -mtime +5 -ok rm { } \;

<rm ... ./conf/httpd.conf >? n

按y键删除文件,按n键不删除。

任何形式的命令都可以在-exec选项中使用。

在下面的例子中我们使用grep命令。find命令首先匹配所有文件名为“ passwd*”的文件,例如passwd、passwd.old、passwd.bak,然后执行grep命令看看在这些文件中是否存在一个sam用户。

# find /etc -name "passwd*" -exec grep "sam" { } \;

sam:x:501:501::/usr/sam:/bin/bash

1、查找当前用户主目录下的所有文件:

下面两种方法都可以使用

$ find $HOME -print

$ find ~ -print

2、让当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件;

$ find . -type f -perm 644 -exec ls -l { } \;

3、为了查找系统中所有文件长度为0的普通文件,并列出它们的完整路径;

$ find / -type f -size 0 -exec ls -l { } \;

4、查找/var/logs目录中更改时间在7日以前的普通文件,并在删除之前询问它们;

$ find /var/logs -type f -mtime +7 -ok rm { } \;

5、为了查找系统中所有属于root组的文件;

$find . -group root -exec ls -l { } \;

-rw-r--r-- 1 root root 595 10月 31 01:09 ./fie1

6、find命令将删除当目录中访问时间在7日以来、含有数字后缀的admin.log文件。

该命令只检查三位数字,所以相应文件的后缀不要超过999。先建几个admin.log*的文件 ,才能使用下面这个命令

$ find . -name "admin.log[0-9][0-9][0-9]" -atime -7 -ok

rm { } \;

<rm ... ./admin.log001 >? n

<rm ... ./admin.log002 >? n

<rm ... ./admin.log042 >? n

<rm ... ./admin.log942 >? n

7、为了查找当前文件系统中的所有目录并排序;

$ find . -type d | sort

8、为了查找系统中所有的rmt磁带设备;

$ find /dev/rmt -print

三、xargs

xargs - build and execute command lines from standard input

在使用find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。

find命令把匹配到的文件传递给xargs命令,而xargs命令每次只获取一部分文件而不是全部,不像-exec选项那样。这样它可以先处理最先获取的一部分文件,然后是下一批,并如此继续下去。

在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;

而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

来看看xargs命令是如何同find命令一起使用的,并给出一些例子。

下面的例子查找系统中的每一个普通文件,然后使用xargs命令来测试它们分别属于哪类文件

#find . -type f -print | xargs file

./.kde/Autostart/Autorun.desktop: UTF-8 Unicode English text

./.kde/Autostart/.directory: ISO-8859 text\

......

在整个系统中查找内存信息转储文件(core dump) ,然后把结果保存到/tmp/core.log 文件中:

$ find / -name "core" -print | xargs echo "" >/tmp/core.log

上面这个执行太慢,我改成在当前目录下查找

#find . -name "file*" -print | xargs echo "" >/temp/core.log

# cat /temp/core.log

./file6

在当前目录下查找所有用户具有读、写和执行权限的文件,并收回相应的写权限:

# ls -l

drwxrwxrwx 2 sam adm 4096 10月 30 20:14 file6

-rwxrwxrwx 2 sam adm 0 10月 31 01:01 http3.conf

-rwxrwxrwx 2 sam adm 0 10月 31 01:01 httpd.conf

# find . -perm -7 -print | xargs chmod o-w

# ls -l

drwxrwxr-x 2 sam adm 4096 10月 30 20:14 file6

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf

用grep命令在所有的普通文件中搜索hostname这个词:

# find . -type f -print | xargs grep "hostname"

./httpd1.conf:# different IP addresses or hostnames and have them handled by the

./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames

on your

用grep命令在当前目录下的所有普通文件中搜索hostnames这个词:

# find . -name \* -type f -print | xargs grep "hostnames"

./httpd1.conf:# different IP addresses or hostnames and have them handled by the

./httpd1.conf:# VirtualHost: If you want to maintain multiple domains/hostnames

on your

注意,在上面的例子中, \用来取消find命令中的*在shell中的特殊含义。

find命令配合使用exec和xargs可以使用户对所匹配到的文件执行几乎所有的命令。

用perm选项

按照文件权限模式用-perm选项,按文件权限模式来查找文件的话。最好使用八进制的权限表示法。

如在当前目录下查找文件权限位为755的文件,即文件属主可以读、写、执行,其他用户可以读、执行的文件,可以用:

$ find . -perm 755 -print

还有一种表达方法:在八进制数字前面要加一个横杠-,表示都匹配,如-007就相当于777,-006相当于666

# ls -l

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf

-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf

-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf

drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam

-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp

# find . -perm 006

# find . -perm -006

./sam

./httpd1.conf

./temp

-perm mode:文件许可正好符合mode

-perm +mode:文件许可部分符合mode

-perm -mode: 文件许可完全符合mode

忽略某个目录

如果在查找文件时希望忽略某个目录,因为你知道那个目录中没有你所要查找的文件,那么可以使用-prune选项来指出需要忽略的目录。在使用-prune选项时要当心,因为如果你同时使用了-depth选项,那么-prune选项就会被find命令忽略。

如果希望在/apps目录下查找文件,但不希望在/apps/bin目录下查找,可以用:

$ find /apps -path "/apps/bin" -prune -o -print

使用find查找文件的时候怎么避开某个文件目录

比如要在/usr/sam目录下查找不在dir1子目录之内的所有文件

find /usr/sam -path "/usr/sam/dir1" -prune -o -print

find [-path ..] [expression] 在路径列表的后面的是表达式

-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o

-print 的简写表达式按顺序求值, -a 和 -o 都是短路求值,与 shell 的 &&和 || 类似如果 -path "/usr/sam" 为真,则求值 -prune , -prune 返回真,与逻辑表达式为真;否则不求值 -prune,与逻辑表达式为假。如果 -path "/usr/sam" -a -prune 为假,则求值 -print ,-print返回真,或逻辑表达式为真;否则不求值 -print,或逻辑表达式为真。

这个表达式组合特例可以用伪码写为

if -path "/usr/sam" then

-prune

else

-print

避开多个文件夹

find /usr/sam \( -path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -print

圆括号表示表达式的结合。

\ 表示引用,即指示 shell 不对后面的字符作特殊解释,而留给 find 命令去解释其意义。

查找某一确定文件,-name等选项加在-o 之后

#find /usr/sam \(-path /usr/sam


特别推荐

广而告之