find full analysis

The find command is the most used command to find files in the linux world

The simplest usage is as follows

find dir -d(depth) 1 -type f(f file d folder) -ctime -1d

-atime 最后的访问时间
s       second
m       minute (60 seconds)
h       hour (60 minutes)
d       day (24 hours)
w       week (7 days)

Any number of units may be combined in one -atime argument, for
example, ``-atime -1h30m''.  Units are probably only useful when
used in conjunction with the + or - modifier.
- 表示之内
+ 表示之外
没有 表示包含并且大于
atime access time
mtime modify time
ctime create time

For example -mtime +1 is more than
1 day -1 within one day
1 1 day or more than one day

Without unit, the default is d [day]

You can use stat to view detailed information about a specific file

Now let's take a closer look at the parameters commonly used by the find command

what is the parameter name illustrate
-name The name can be a pattern [is the most basic regular] such as -name '[a-z0-9] .txt' The regular expression to find the name uses the glob pattern to find [] [-] * . *
-iname posix regex has no modifiers, so the way to ignore case is to use -iname
-perm Permission-perm 664 Find files with 664; there is another way of expression: add a horizontal bar - in front of the octal number, indicating that at least this permission is included; find files or directories with permissions of 644 (requires full compliance) find ./ -perm 664Find user/group permissions For read and write, other user permissions are read (other permissions are not limited) files or directoriesfind ./ -perm -664
-depth Folder search depth
-prune Remove a directory from searching; be careful when using the -prune option, because if you also use the -depth option, the -prune option will be ignored by the find command. If you want to search for files in the test directory, but do not want to search in the test/test3 directory, you can use -path find test -path "test/test3" -prune -o -printhere is an absolute path, so the -path is preferably "*test/test3" like this
-type d folder f file l for link
-exec Perform additional operations on the content after the search-exec ls {} \; 注意这个转义的 \;
-ok Adding a confirmation will confirm and replace the use of -exec when printing, but you need to confirm that the above -exec ls {} \;becomes -ok ls {} \;interactive
-print It will print the full name of the searched file. For example find ~/Downloads/ -name "专供*" -print -exec cat {} \;·, it will cat the file and print the file name. If there is no -print, the file name will not be printed.
-regex Find the name of the file by regular expression find ~/Downloads/ -regex . For special use. -print -exec cat {} \; Find the full name!!! [This is more annoying] All must pay attention to the .*专供.*front and back .*can find specific specific files in a folder
-name Finding files by name is not the same as * in regular expressions* This matches any number of characters==This is to verify only the file name regex is to verify all strings of the file name==
-exec ls {} + The plus sign means to wait all output until the last one for ls to execute
-atime 【 access time】 find ./ -mtime -2d #查找两天内的文件 find ./ -mtime +2d #两天以上的 find ./ -mtime 2d #两天以上的以及两天以上的==Note that even if you ls the file, the access time of the file will be modified== View through stat
-mtime 【modified time 】 Ditto
-ctime 【changed time】 Ditto
-newer Find files with a newer time than the content of file abc find ./ -newer abc
-anewer Find files whose access time is newer than the content of file abc find ./ -anewer abc
-empty ==Find empty files or empty directories==
-delete Delete operation is dangerous
-user user user
-group group filter
-nouser no user
-nogroup file without group
find ./ -executable ! -readable 查找有执行权限但没有可读权限的文件 这个完全可以在权限里面设置 这个readable 和 executable 只有在 centos linux 里面有 unix 木有
-size 查找文件大小
-prune 不包含文件夹 或者文件
-path 根据路径查找文件 复合pattern
-maxdepth 最高深度
-mindepth 最浅深度
取反操作符

-perm 权限 的例子

查找权限为644的文件或目录(需完全符合)

find ./ -perm 664

查找权限不是 644 的文件或者目录

find ./ ! -perm 644 # ! 表示取反

查找用户/组权限为读写,其他用户权限为读(其他权限不限)的文件或目录

find ./ -perm -664

-664 包含的含义是“至少包含 644”

下面的含义是 other 包含 read

find ./ -perm -o=r 或者 find ./ -perm -o=rw # 里面的的选项有 -o -u -g 权限有 rwx

在centos 等linux 中还支持
find / -maxdepth 2 -perm /u=s 这样的的语法


-size 例子

查找文件size小于10个字节的文件或目录
find ./ -size -10c

查找文件size等于10个字节的文件或目录
find ./ -size 10c

查找文件size大于10个字节的文件或目录
find ./ -size +10c

查找文件size小于10k的文件或目录
find ./ -size -10k

查找文件size小于10M的文件或目录
find ./ -size -10M

查找文件size小于10G的文件或目录
find ./ -size -10G

-prune 的例子

参考 https://stackoverflow.com/questions/1489277/how-to-use-prune-option-of-find-in-sh

[-prune man 里面这样说 永远返回真,它让find 忽略满足条件的 目录,假如 -d 指定的话 这个参数无用]

The thing I’d found confusing about about -prune is that it’s an action (like -print), not a test (like -name). It alters the “to-do” list, but always returns true.
【-prune更像是一个语句,就像-print 一样 】

The general pattern 【语法】for using -prune is this:

==find [path] [conditions to prune] -prune -o \ [your usual conditions] [actions to perform]==

You pretty much always want the the -o immediately after -prune, because that first part of the test (up to including -prune) will return false for the stuff you actually want (ie: the stuff you don’t want to prune out).
所有 -prune 后面要紧跟 -o [-o -a 还有 ! 或 与 非]
-o 后面的内容才是你 想要的

Here’s an example:

find . -name .snapshot -prune -o -name '*.foo' -print

This will find the “.foo” files that aren’t under “.snapshot” directories. In this example, -name .snapshot is the “tests for stuff you want to prune”, and -name ‘.foo’ -print is the “stuff you’d normally put after the path”.

上面有一点错误 -name .snapshot 不仅是对文件夹的筛选,对文件一样的筛选【作者提示 一定要在-o 语句 最后加上 -print 否则也不会有效】

Important notes:

If all you want to do is print the results you might be used to leaving out the -print action. You generally don’t want to do that when using -prune.

The default behavior of find is to “and” the entire expression with the -print action if there are no actions other than -prune (ironically) at the end. That means that writing this:

find . -name .snapshot -prune -o -name '*.foo'              # DON'T DO THIS

is equivalent to writing this:

find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS

which means that it’ll also print out the name of the directory you’re pruning, which usually isn’t what you want.

上面的意思是如果没有最后的print find 命令会将后面的所有条件综合起来 然后在最后加一个 -print 那样的话 -o 【or】 就失去了我们想要的结果

Instead it’s better to explicitly specify the -print action if that’s what you want:

find . -name .snapshot -prune -o -name '*.foo' -print       # DO THIS

If your “usual condition” happens to match files that also match your prune condition, those files will not be included in the output. The way to fix this is to add a -type d predicate to your prune condition.

下面是作者展示的一个例子 在本文件夹中既有一个文件叫 .gitignore 又有一个文件夹叫 .git 左右想剔除所有含有.git字样的文件夹但是想查看包含.git字样的文件

find ./ -type d -name ".git*" -prune -o -type f -print

For example, suppose we wanted to prune out any directory that started with .git (this is admittedly somewhat contrived – normally you only need to remove thing named exactly .git), but other than that wanted to see all files, including files like .gitignore. You might try this:

find . -name '.git*' -prune -o -type f -print               # DON'T DO THIS

This would not include .gitignore in the output. Here’s the fixed version:

find . -type d -name '.git*' -prune -o -type f -print       # DO THIS

Extra tip: if you’re using the GNU version of find, the texinfo page for find has a more detailed explanation than its manpage (as is true for most GNU utilities).

参考 http://www.cnblogs.com/peida/archive/2012/11/16/2773289.html

上面的文章有个例子讲到

-a 和 -o 都是短路求值,与 shell 的 && 和 || 类似如果

查看下面的例子

例子1

find . -path "*testone" -prune -a -exec ls -al {} \;

上面的例子 查找path 包含 testone 的文件 并把它打印出来 这个例子有点多此一举

相当于

find . -path "*testone" -exec ls -al {} \ ;

测试下来效果一样

例子2【摘抄】

避开多个文件夹:
命令:

find test \( -path test/test4 -o -path test/test3 \) -prune -o -print 

上面的例子很多人会测试失败原因是
-path 接受的是一个 最好使用 *test4 代替 test/test4

我本地测试 避开 .git 和testone 文件夹

find . -type d -a \( -name ".git" -o -name "testone" \) -prune -o -print 

==一定要记得 -o !!!!==

-depth 命令例子

参数-depth 的意思是:在处理目录以前首先处理目录下的子内容。
也即是说在不加-depth的时候, 处理顺序是首先处理目录本身,然后处理目录下的子内容。加不加-depth参数,会影响输出结构的输出顺序。

-mindepth 最少深度

dingmac@php_test$ find ./ -name 'test*' -depth -print
.//test.php
.//test1.php
.//test_2.php
.//test_global.php
.//testone/test1.txt
.//testone/test2.txt
.//testone
dingmac@php_test$ find ./ -name 'test*'  -print
.//test.php
.//test1.php
.//test_2.php
.//test_global.php
.//testone
.//testone/test1.txt
.//testone/test2.txt

-d n 如果-d 后面直接跟参数就是指定层的满足条件的文件输出

demo

dingmac@php_test$ find ./ -name 'test*' -d 1 -print
.//test.php
.//test1.php
.//test_2.php
.//test_global.php
.//testone
dingmac@php_test$ find ./ -name 'test*' -d 2 -print
.//testone/test1.txt
.//testone/test2.txt
dingmac@php_test$ find ./ -name 'test*' -d 3 -print
dingmac@php_test$ find ./ -name 'test*' -d 4 -print
dingmac@php_test$ find ./ -name 'test*' -d 5 -print
.//testone/first/second/third/testwow.txt

再查看一个 mindepth 的例子 指定最少深度

dingmac@php_test$ find ./ -name 'test*' -mindepth 1 -print
.//test.php
.//test1.php
.//test_2.php
.//test_global.php
.//testone
.//testone/first/second/third/testwow.txt
.//testone/test1.txt
.//testone/test2.txt
dingmac@php_test$ find ./ -name 'test*' -mindepth 2 -print
.//testone/first/second/third/testwow.txt
.//testone/test1.txt
.//testone/test2.txt
dingmac@php_test$ find ./ -name 'test*' -mindepth 3 -print
.//testone/first/second/third/testwow.txt

参考 http://www.binarytides.com/linux-find-command-examples/
https://kb.iu.edu/d/admm

相同的可以使用-maxdepth 用来表示最大深度
demo find -name "*test* -maxdepth 2" 查找最深是2的文件

如果想取非,使用 ! 表示非
demo find -name "*test*" 查找文件中不包含 test 的文件

连字符 包含 -a -o ! 两个不带任何参数的时候默认是 “并”

-perm 补充

参考

http://www.cnblogs.com/gaojian/archive/2013/01/25/2876046.html
https://www.computerhope.com/unix/ufind.htm

我百度了一下 出现的各种帖子都是只给个例子 比如

find ./ -perm 666 这样的命令 就算把-perm 这个参数讲了 要不然就列几个例子 笼统的说明一下,更深的就没有了

所以下面在整理一下 -perm 这个参数的使用

mac 中 man find 找到 -perm 可以自己研究,mac是unix核和linux 有点差别

-perm 参数支持好几种方式

  1. -perm mode 精确匹配 差一点都不行

    可以使用数字表示和字符表示
    demo:

    find . -perm 642 
    ./timg.gif # 结果
    
    find . -perm u=rw,g=r,o=w #和上面结果一样使用","连接 也是精确查找642
  2. -perm -mode 包含就可以 比如 110 010 010 [622] 比如 有个文件的权限是 110 101 110 [656] 是无法被圈的 110 011 110 [634] 可以查找到

    demo:

    dingmac@linux_test$ ll
    total 8
    drwxr-xr-x   5 dingmac  staff   170B  9 13 18:38 ./
    drwx------+ 37 dingmac  staff   1.2K  9 17 22:37 ../
    -rw-r-xrw-   1 dingmac  staff     0B  9 13 17:23 file1.txt*
    -rw--wxr--   1 dingmac  staff     0B  9 13 17:23 file2.txt*
    -rwxr-xr-x   1 dingmac  staff    44B  9 13 18:38 list_user.awk*
    dingmac@linux_test$ find . -perm 642
    dingmac@linux_test$ find . -perm -642
    ./file1.txt
    
    
    #如果要使用rwx 字符表示 和上面的一样
    
    find ./ -perm -u=rw,g=r,o=w
    
    # 出来的结果和上面一样
    
    
    # 注意的是只需要在 第一个上面加 - 就可以了
    
    
    另外需要说明的是 -u=rw,g=r,o=w 这里面的 “=”
    同样可以有+- 替代
    = 表示含有 + 表示大于或者比这个高 其实和 = 没多大差别 - 表示低于都可以 其实 - 没有啥意义 理解上 = + 一个意思就可以了
    
    所以 下面两个命令是一样的
    
    dingmac@linux_test$ find ./ -perm -u+rw,g+x,o+rw
    .//file1.txt
    dingmac@linux_test$ find ./ -perm -u=rw,g=x,o=rw
    .//file1.txt

-perm +mode 其实是一个与或概念
1 xor 1 = 1
1 xor 0 = 0
0 xor 0 = 0

如果我们要查找 g 有写权限的文件 比如下面这个文件 将不被筛选
100 100 101 [445] 下面是例子

dingmac@linux_test$ ll
total 8
drwxr-xr-x   5 dingmac  staff   170B  9 13 18:38 ./
drwx------+ 37 dingmac  staff   1.2K  9 17 22:37 ../
-r--r--r-x   1 dingmac  staff     0B  9 13 17:23 file1.txt*
-rw--wxr--   1 dingmac  staff     0B  9 13 17:23 file2.txt*
-rwxr-xr-x   1 dingmac  staff    44B  9 13 18:38 list_user.awk*
dingmac@linux_test$ find . -perm +g=x
.
./file2.txt
./list_user.awk
dingmac@linux_test$ find . -perm +g+x
.
./file2.txt
./list_user.awk

linux 系统中还有一个 /mode
类似于 mac 中的 +

其他的就没啥

补充1

查找符合条件的文件,按照大小排序

需要用到命令有 find 还有sort
但是有一个问题想要获得 human readble 的方式显示就会有问题

demo 查看列表

dingmac@php_test$ find . -name "*test*" -type f -exec ls -al {} \; | sort -k 5 -nr
-rw-r--r--  1 dingmac  staff  18696  9 20 12:16 ./awk_test.txt
-rw-r--r--@ 1 dingmac  staff  1038  9 19 17:40 ./test_2.php
-rw-r--r--@ 1 dingmac  staff  407  9 19 15:59 ./test.php
-rw-r--r--  1 dingmac  staff  272  9 14 15:20 ./test1.php
-rw-r--r--  1 dingmac  staff  77  9 18 14:05 ./test_global.php
-rw-r--r--  1 dingmac  staff  0  9 20 23:05 ./testone/first/second/third/testwow.txt
-rw-r--r--  1 dingmac  staff  0  9 20 22:01 ./testone/test2.txt
-rw-r--r--  1 dingmac  staff  0  9 20 22:01 ./testone/test1.txt

但是想看到human readable的形式就不能按照上面的方法

我尝试过下面的方法 我发现ls 命令中有一个参数 -S 是按照size 倒序排列的

demo

dingmac@php_test$ ls -alShd  test*
-rw-r--r--@ 1 dingmac  staff   1.0K  9 19 17:40 test_2.php
-rw-r--r--@ 1 dingmac  staff   407B  9 19 15:59 test.php
-rw-r--r--  1 dingmac  staff   272B  9 14 15:20 test1.php
drwxr-xr-x  6 dingmac  staff   204B  9 20 23:05 testone
-rw-r--r--  1 dingmac  staff    77B  9 18 14:05 test_global.php

是ok的
-d 的命令是将文档当做文件处理 不循环列出下面的文件

但是在find命令 中使用的时候会有问题下面是demo

dingmac@php_test$ find . -name "*test*" -type f -exec ls -alSh {} \; 
-rw-r--r--  1 dingmac  staff    18K  9 20 12:16 ./awk_test.txt
-rw-r--r--@ 1 dingmac  staff   407B  9 19 15:59 ./test.php
-rw-r--r--  1 dingmac  staff   272B  9 14 15:20 ./test1.php
-rw-r--r--@ 1 dingmac  staff   1.0K  9 19 17:40 ./test_2.php
-rw-r--r--  1 dingmac  staff    77B  9 18 14:05 ./test_global.php
-rw-r--r--  1 dingmac  staff     0B  9 20 23:05 ./testone/first/second/third/testwow.txt
-rw-r--r--  1 dingmac  staff     0B  9 20 22:01 ./testone/test1.txt
-rw-r--r--  1 dingmac  staff     0B  9 20 22:01 ./testone/test2.txt

上面就完全出错误了

#查找文件最大的文件
find ./ -type f -exec ls {} \; | sort -nr |head -5
# 找最小的文件
find ./-type f -exec ls {} \; |sort -n  | head -5

ls -s 显示所占的block 数 Display the number of file system blocks actually used by each file

暂时没有找到合适的方法

找到一个 可行版本
https://askubuntu.com/questions/80244/how-do-i-sort-by-human-readable-sizes-numerically

但要自己写

终于找到了方法 下面是demo

dingmac@php_test$ find . -type f -name "*test*" -exec  ls -lShr {} \+
-rw-r--r--  1 dingmac  staff     0B  9 20 22:01 ./testone/test2.txt
-rw-r--r--  1 dingmac  staff     0B  9 20 22:01 ./testone/test1.txt
-rw-r--r--  1 dingmac  staff     0B  9 20 23:05 ./testone/first/second/third/testwow.txt
-rw-r--r--  1 dingmac  staff    77B  9 18 14:05 ./test_global.php
-rw-r--r--  1 dingmac  staff   272B  9 14 15:20 ./test1.php
-rw-r--r--@ 1 dingmac  staff   407B  9 19 15:59 ./test.php
-rw-r--r--@ 1 dingmac  staff   1.0K  9 19 17:40 ./test_2.php
-rw-r--r--  1 dingmac  staff    18K  9 20 12:16 ./awk_test.txt

关键是 ==“+”==

但是有一个问题是 上面的命令不能对所有文件进行操作

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325881832&siteId=291194637