您的位置:首页 > 运维架构 > Shell

shell 文件查找命令find

2017-04-06 12:09 288 查看

文件查找 find

------目录------
1、查找条件
2、文件查找后的处理
----------------

1、查找条件

1.1)文件名称的匹配 && 多条件名称匹配
这里可以使用正则表达式来进行匹配,多条件中的AND -a OR -o来进行拼接

root@docker-host-03:~# find . \( -name "list*" -o -name "Config*" \) -print
./list
./tools/Django-1.7.9/django/views/generic/list.py
./tools/Django-1.7.9/django/contrib/comments/templates/comments/list.html
./tools/Django-1.7.9/build/lib.linux-x86_64-2.7/django/views/generic/list.py
./tools/Django-1.7.9/build/lib.linux-x86_64-2.7/django/contrib/comments/templates/comments/list.html
./tools/Django-1.7.9/tests/generic_views/templates/generic_views/list.html
./test_shell/module/Config.sh
./list2 正则方式查找文件名称
. 匹配任意一个
* 重复之前一任意次
+重复之前一次或一次以上
?前一个字符匹配一个或0个
root@docker-host-03:~# find ./tmp –regex ".*\(\.py\|\.sh\)$"
./tmp/.pythontab.py
./tmp/install.sh
./tmp/testpty.py
./tmp/test.py
./tmp/test.sh

利用正则且多条件的名称匹配
root@docker-host-03:~# find ./tmp \( ! -regex ".*py.*" -a -name"*.c" \)
./tmp/tcpportping.c
./tmp/pid.c
./tmp/test.c
root@docker-host-03:~# find ./tmp -name "*.c"
./tmp/tcpportping.c
./tmp/pid.c
./tmp/test.c
./tmp/test.py.c

1.2)基于查找路径的搜索

限定搜索路径的深度
root@docker-host-03:~# find ./ -maxdepth 2 -type f -name"*.py"
./tmp/.pythontab.py
./tmp/testpty.py
./tmp/test.py

1.3)按照搜索的类型来寻找
-f 文件
-d 目录
-l 软连接
-c 字符设备
-b 块设备

1.4)按照搜索的时间来搜索
-atime : 用户最近一次访问文件的时间
-mtime : 用户最近一次修改的时间
-ctime :文件元数据(例如权限或所有权)最后一次修改的时间
上面一天为单位
-cmin -mmin -amin 三个以分钟为单位

root@docker-host-03:~# find ./ -type f -atime -7 -regex".*\(\.py\|\.sh\)$"
./test.sh
./test_shell/module/Config.sh
./test_shell/module/test1.sh
./test_shell/demo1.sh
./test_shell/module2/mail.sh
./test_shell/main.sh
./tmp/test.sh

1.5)基于搜索的大小来搜索

root@docker-host-03:~# find ./ -size +2k -type f -atime-7 -regex ".*\(\.py\|\.sh\)$"
root@docker-host-03:~# find ./ -size -2k -type f -atime-7 -regex ".*\(\.py\|\.sh\)$"
./test.sh
./test_shell/module/Config.sh
./test_shell/module/test1.sh
./test_shell/demo1.sh
./test_shell/module2/mail.sh
./test_shell/main.sh
./tmp/test.sh

1.6)基于搜索的权限&&所有者来搜索
root@docker-host-03:~# find ./ -perm 644 -size -2k -type f-atime -7 -regex ".*\(\.py\|\.sh\)$"
./test_shell/module/Config.sh
./test_shell/module2/mail.sh

root@docker-host-03:~# find ./ -user root -perm644 -size -2k -type f -atime -7 -regex ".*\(\.py\|\.sh\)$"
./test_shell/module/Config.sh
./test_shell/module2/mail.sh

2、查找后的操作
两种方式来进行操作的拼接
2.1)通过-exec { } \; 来进行和其他命令的结合

root@docker-host-03:~# find ./ -maxdepth 2-type f -name "*.py" -exec ls -lh {}\;
-rw-r--r-- 1 root root 71 Apr 18 2016 ./tmp/.pythontab.py
-rw-r--r-- 1 root root 124 Nov 10 16:37./tmp/testpty.py
-rw-r--r-- 1 root root 1.3K May 3 2016./tmp/test.py

我们可以这样理解这个命令格式。我们将-exec \: 当成是使用命令拼接的固定格式,而{}就代表着通过find所查找的文件。
root@docker-host-03:~# find ./ -maxdepth 2-type f -name "*.py" -exec cat {} \; >> ./findcont
root@docker-host-03:~# ls -lh
total 40K
lrwxrwxrwx 1 root root 12 Jan 4 11:30 backup -> /data/backup
-rw-r--r-- 1 root root 2.9K Apr 1 15:17findcont

但是这里一个弊端就是我们能够接受的命令很有限,如果我们希望将这个文件做多步复杂的处理的话。我们可能需要通过一个函数或者一个脚本传参的形式来完成。

2.2)通过xargs来实现命令结合

Xargs 通过管道接受表述输入,并且将此其输入转化为特定名的命令行参数。
Bash黑客喜欢单行命令,单行命令是一个命令序列,各命令之间不使用分号,能够更高效处理,对于文本处理也是。Xargs是构建单行命令不可或缺的重要组件。
我们这样来理解,就是将从标准输入获取的内容,当成参数再次输出给相应的命令。多行的标准输入

Xargs的预备知识
-d 执行标准输入的分个数
-n 对标准输入按照分隔符分割后,输出多少个元素
-I 指定一个标识符来代替参数。后续如果出现过个标识符,会被替换为具体的参数。

但在这里需要注意一个误区就是我们当输入的标准输入(也就是|管道的前端)输出的分隔符不确定或者不能明确知道以什么来分割的时候,对于后续要加上的操作就要小心。
比如下面这个例子,我们有的文件名称中包含空格,我们通过find查找出来,通过 |xargs 之后被分割成了多个参数,如果我们后面结合的命令参数是rm –rf 的话,那么我们会将原本是123123目录下的内容全部删掉。而我们本意是删掉123123 123123.asdf文件。

root@docker-host-03:~# find ./ -maxdepth1 -name "123*" | xargs -n 1
./123123
123123.asdf
./123123
root@docker-host-03:~# ls -lh
total 44K
drwxr-xr-x 2 root root 4.0K Apr 1 16:19123123
-rw-r--r-- 1 root root 0 Apr 1 16:18 123123 123123.asdf

如何避免这个问题,我们需要在xargs 加上-0(数字) 来限定以\0为界定符
root@docker-host-03:~# find ./ -maxdepth 1-name "123*" |xargs -0
./123123 123123.asdf
./123123

root@docker-host-03:~# find ./ -maxdepth 1-name "123*" |xargs
./123123 123123.asdf ./123123

Xargs和find 的结合
Xargs和find的结合就是通过find 查找到相应文件,通过|管道输出给xargs,然后xargs 将输入的文件进行分割,然后通过-I 指定一个参数替代标识符。比如和-exec 的{}一样,那我们的命令格式就会变成是一下这样的。

root@docker-host-03:~# find ./ -maxdepth 1-type f -name "*.sh" | xargs -I {} ls -lh {}
-rwxr-xr-x 1 root root 13 Apr 1 15:22 ./test.sh
-rw-r--r-- 1 root root 0 Apr 1 16:38 ./123.sh

#这里讲标识设置为1,后面就是用1来代表。这里有部分符号是不能作为标识符的。
root@docker-host-03:~# find ./ -maxdepth 1-type f -name "*.sh" | xargs -I 1 ls -lh 1
-rwxr-xr-x 1 root root 13 Apr 1 15:22 ./test.sh
-rw-r--r-- 1 root root 0 Apr 1 16:38 ./123.sh
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shell exec find