shell命令--find

shell命令--find

0、find命令的专属图床

点此快速打开文章图床_shell命令find

1、find命令的功能说明

find 命令用来在指定目录下查找文件。任何位于参数之前的字符串都将被视为欲查找的目录名。如果使用该命令时,不设置任何参数,则 find 命令将在当前目录下查找子目录与文件。并且将查找到的子目录和文件全部进行显示。

2、find命令的语法格式

SYNOPSIS
    find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]

3、find命令的选项说明

帮助

[root@MineGi ~]# find --help
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

default path is the current directory; default expression is -print
expression may consist of: operators, options, tests, and actions:

operators (decreasing precedence; -and is implicit where no others are given):
   ( EXPR )   ! EXPR   -not EXPR   EXPR1 -a EXPR2   EXPR1 -and EXPR2
   EXPR1 -o EXPR2   EXPR1 -or EXPR2   EXPR1 , EXPR2

positional options (always true): -daystart -follow -regextype

normal options (always true, specified before other expressions):
   -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
   --version -xautofs -xdev -ignore_readdir_race -noignore_readdir_race

tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N
   -cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME
   -ilname PATTERN -iname PATTERN -inum N -iwholename PATTERN -iregex PATTERN
   -links N -lname PATTERN -mmin N -mtime N -name PATTERN -newer FILE
   -nouser -nogroup -path PATTERN -perm [-/]MODE -regex PATTERN
   -readable -writable -executable
   -wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N
   -used N -user NAME -xtype [bcdpfls]
   -context CONTEXT

选项

  • '-H':表示只跟随命令行中指定的符号连接,
  • '-L':表示跟随所有的符号连接,
  • '-P':是默认的选项,表示不跟随符号连接。
  • -D debugoptions. :打印诊断信息
  • -Olevel Enables query optimisation.:允许查询优化

EXPRESSIONS

EXPRESSIONS:表达式可能由下列成份组成:操作符、选项、测试表达式以及动作

  1. 操作符为and、or、!的组合

    ! expr True if expr is false.        
    -not expr   Same as ! expr, but not POSIX compliant.
    expr1 expr2   implied "and"; expr2 is not evaluated if expr1 is false.
    expr1 -a expr2  Same as expr1 expr2.
    expr1 -and expr2 Same as expr1 expr2, but not POSIX compliant.
    expr1 -o expr2  Or; expr2 is not evaluated if expr1 is true.
    expr1 -or expr2  Same as expr1 -o expr2, but not POSIX compliant.
    expr1 , expr2   List; both expr1 and expr2 are always evaluated.  The  value  of expr1 is discarded; the value of the list is the value of expr2.The comma operator can be useful for searching for several  different  types  of thing, but traversing the filesystem hierarchy only once.  The -fprintf action can be used to list the  various matched items into several different output files.
    
  2. 设置项针对这次查找任务,而不是仅仅针对某一个文件,设置项总是返回true

    位置选项 (总是真): -daystart -follow -regextype
    普通选项 (总是真,在其它表达式前指定):
    -depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf
    --version -xdev -ignore_readdir_race -noignore_readdir_race
    
  3. 测试项(test)则不同,它针对具体的一个文件进行匹配测试,如-name,-user等,返回true或者false

    测试项如下:

    -name  -type  -ok  -newer -perm  -atime, -ctime, -depth, -group,  -links,  -mtime,-nogroup,  -nouser,  -print,  -prune,  -size,  -user  and  -xdev -atime,  -ctime,  -depth,  -group,  -links,  -mtime,-nogroup,  -nouser,  -perm,  -print,  -prune, -size,-user and –xdev
    

    测试项说明:

    -name filename:查找名为filename的文件
    -perm:按执行权限来查找
    -user username:按文件属主来查找
    -group groupname:按组来查找
    -mtime -n/+n:按文件更改时间来查找文件,-n指n天以内,+n指n天以前
    -atime -n/+n:按文件访问时间来查GIN: 0px">
    -ctime -n/+n:按文件创建时间来查找文件,-n指n天以内,+n指n天以前
    -nogroup:查无有效属组的文件,即文件的属组在/etc/groups中不存在
    -nouser:查无有效属主的文件,即文件的属主在/etc/passwd中不存
    -newer f1/!f2找文件,-n指n天以内,+n指n天以前 
    -ctime -n/+n:按文件创建时间来查找文件,-n指n天以内,+n指n天以前 
    -nogroup:查无有效属组的文件,即文件的属组在/etc/groups中不存在
    -nouser:查无有效属主的文件,即文件的属主在/etc/passwd中不存
    -newer f1/!f2:查更改时间比f1新但比f2旧的文件
    -type b/d/c/p/l/f:查是块设备、目录、字符设备、管道、符号链接、普通文件
    -size n[c]:查长度为n块[或n字节]的文件
    -depth:使查找在进入子目录前先行查找完本目录
    -fstype:查更改时间比f1新但比f2旧的文件
    -type b/d/c/p/l/f:查是块设备、目录、字符设备、管道、符号链接、普通文件
    -size n[c]:查长度为n块[或n字节]的文件
    -depth:使查找在进入子目录前先行查找完本目录
    -fstype:查位于某一类型文件系统中的文件,这些文件系统类型通常可 在/etc/fstab中找到
    -mount:查文件时不跨越文件系统mount点
    -follow:如果遇到符号链接文件,就跟踪链接所指的文件
    -cpio %;:查位于某一类型文件系统中的文件,这些文件系统类型通常可 在/etc/fstab中找到
    -mount:查文件时不跨越文件系统mount点
    -follow:如果遇到符号链接文件,就跟踪链接所指的文件
    -cpio:对匹配的文件使用cpio命令,将他们备份到磁带设备中
    -prune:忽略某个目录
    
  4. 动作项(action)则是对某一个文件进行某种动作(最常见的如-print)

    actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print 
          -fprint0 FILE -fprint FILE -ls -fls FILE -prune – -quit
          -exec COMMAND ; -exec COMMAND {} + -ok COMMAND ;
          -execdir COMMAND ; -execdir COMMAND {} + -okdir COMMAND ;
    
    -print: find命令将匹配的文件输出到标准输出。
    -ls:使用ls -dils 格式将匹配的文件输出到标准输出。
    -exec: find命令对匹配的文件执行该参数所给出的shell命令。
    -ok: 和-exec的作用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每一个命令之前,都会给出提示,让用户来确定是否执行。
    

4、find命令的实践操作

模拟环境

清空目录

cd && rm -rf /test  -->将之前的实验环境删除掉。提示:rm -rf 谨慎使用!
mkdir /test && cd /test

创建目录及文件

mkdir -p test_dir/dir
touch test_dir/dir/file.txt
touch test_file{1..3}.txt test_script.sh test_python.py

范例1:-H –L –P 指定对符号连接的处理方式

ln -s /bin rootbin
find -P . -name pwd
find -L . -name pwd
find -H rootbin . -name pwd

范例2:根据文件名或者正则表达式进行匹配

列出当前目录及子目录下所有文件和目录

find

在当前目录下查找以xx结尾的文件名,比如 .txt

find . -name "*.txt"

在当前目录下查找以xx结尾的文件名,比如 .txt,但忽略大小写

find . -name "*.TXT"
find . -iname "*.TXT"

当前目录及子目录下查找所有以多个后缀结尾的文件,比如 .py 或者 .sh(取并集)

find . -name "*.py" -o -name "*.sh"
mv *.py /tmp
!find

当前目录及子目录下查找所有以多个字符集的文件,比如 test 和 .sh(取交集)

find . -name "*.py" -a -name "*.sh"
find . -name "test*" -a -name "*.sh"

找出当前目录下不是以.sh结尾的文件(注意 ! 位置)

find . ! -name "*.sh"

范例3:匹配文件路径或者文件

find /usr/ -path "*openssh*"

范例4:基于正则表达式匹配文件路径

find . -regex ".*\(\.sh\|\.py\)$"

同上,但忽略大小写

find . -iregex ".*\(\.SH\|\.PY\)$"

范例5:搜索但跳出指定的目录

查找当前目录或者子目录下所有以 .txt 结尾的文件,但是跳过子目录 test_dir

find . -path "./test_dir" -prune -o -name "*.txt"  -->跳过
find . -name "*.txt"  -->不跳过

范例6:根据文件类型进行搜索

find . -type d

范例7:基于目录深度搜索 向下最大深度限制为1

find
find . -maxdepth 1
find . -mindepth 2

范例8:根据文件时间戳进行搜索

find . -type f 时间戳

UNIX/Linux文件系统每个文件都有三种时间戳:

  • 访问时间(-atime/天,-amin/分钟):用户最近一次访问时间。
  • 修改时间(-mtime/天,-mmin/分钟):文件最后一次修改时间。
  • 变化时间(-ctime/天,-cmin/分钟):文件数据元(例如权限等)最后一次修改时间。

搜索最近七天内被访问过的所有文件

find . -type f -atime -7

搜索恰好在七天前被访问过的所有文件

find . -type f -atime 7

搜索超过七天内被访问过的所有文件

find . -type f -atime +7

搜索访问时间超过10分钟的所有文件

find . -type f -amin +10

找出比 test_file1.txt 修改时间更长的所有文件

find . -type f -newer test_file1.txt

范例9:根据文件大小进行匹配

搜索大于10KB的文件

find . -type f -size +10k

搜索小于10KB的文件

find . -type f -size -10k

搜索等于10KB的文件

find . -type f -size 10k

范例10:根据文件权限/所有权进行匹配

当前目录下搜索出权限为 644 的文件

find . -type f -perm 644

找出当前目录下权限不是 644 的 txt 文件

chmod 555 test_file1.txt
ll
find . -type f -name "*.txt" ! -perm 644

范例11:根据用户/用户组进行匹配

找出当前目录用户 root 拥有的所有文件

id sshd
chown sshd. test_file1.txt
ll
find . -type f -user root
find . -type f ! -user root

找出当前目录用户组 root 拥有的所有文件

ll
find . -type f -group root
find . -type f ! -group root

范例12:-delete 删除匹配文件

删除当前目录下所有 .sh 文件

ll
find . -type f -name "*.sh"
find . -type f -name "*.sh" -delete
find . -type f -name "*.sh"

范例13:列出匹配文件

find . -type f -name "*.txt" -ls

范例14:借助 -exec 选项与其他命令结合使用

​ find是我们很常用的一个Linux命令,但是我们一般查找出来的并不仅仅是看看而已,还会有进一步的操作,这个时候exec的作用就显现出来了。exec选项后面跟随着所要执行的命令或脚本,然后是一对儿{ },一个空格和一个\,最后是一个分号。

​ -exec 参数后面跟的是command命令,它的终止是以;为结束标志的,所以这句命令后面的分号是不可缺少的,考虑到各个系统中分号会有不同的意义,所以前面加反斜杠。{} 花括号代表前面find查找出来的文件名。

找出当前目录下所有 root 的文件,并把所有权更改为用户 testuser

useradd testuser
ll
find . -type f -user root -exec chown testuser. {} \;
ll

查找当前目录下所有 .txt 文件并把他们拼接起来写入到 all_txt 文件中

cat all_txt
echo test1 >test_file1.txt
echo test2 >test_file2.txt
find . -type f -name "*.txt" -exec cat {} \;> all_txt
cat all_txt

将30天内的 .txt 文件复制到 /tmp 目录中

ls
ls /tmp/
find . -type f -mtime -30 -name "*.txt" -exec cp {} /tmp \;
ls
ls /tmp/

找出当前目录下所有.txt文件并以“File:文件名”的形式打印出来

find . -type f -name "*.txt" -exec printf "File: %s\n" {} \;

因为单行命令中 -exec 参数中无法使用多个命令,以下方法可以实现在 -exec 之后接受多条命令

-exec sh test_script.sh {} \;

范例15:find 的 ok 操作

-ok 和 -exec 行为一样,不过它会给出提示,让用户决定是否执行相应的操作。

找出当前目录下所有的 _txt 文件并删除

ls *_txt
find . -name "*_txt" -ok rm -f {} \;
ls *_txt

范例16:find 与 xargs

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

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

​ 在有些系统中,使用-exec选项会为处理每一个匹配到的文件而发起一个相应的进程,并非将匹配到的文件全部作为参数一次执行;这样在有些情况下就会出现进程过多,系统性能下降的问题,因而效率不高;而使用xargs命令则只有一个进程。另外,在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。


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

find . -type f | xargs file
find . -type f -print | xargs file

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

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

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

echo 'I love linux' >file.txt
find . -type f -print | xargs grep "love"

删除3天以前的所有东西

ll
find . -ctime +3 -exec rm -rf {} \;
find ./ -mtime +3 -print|xargs rm -r -f
ll

删除文件大小为零的文件

ll
find ./ -size 0 | xargs rm -f
ll

将当前所有以 .txt 结尾的文件移动到 test_dir 目录中

ls
find . -type f -name "*.txt" |xargs -i mv {} test_dir
ls
ls test_dir/
find -type f -name "*.txt" |xargs mv -t .
ls
ls test_dir/

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

『MineGi有话说』:快来扫一扫下面链接的二维码,加入我们吧!

posted @ 2020-02-23 08:00  MineGi  阅读(338)  评论(0编辑  收藏  举报