find是Unix/Linux命令行工具箱中最实用的工具之一。xargs是它的一个死党
一、find
find的工作方式如下:沿着文件层次结构向下遍历,匹配符合条件的文件,执行相应的操作。
- 根据文件名或正则表达式搜索
-name
参数指定文件名必须匹配的模式
find . -name '*.txt' -print # 打印当前目录所有的txt文件
类似还有一个-iname
参数,与-name
类似,只不过忽略大小写。
要匹配多个条件中的一个,使用or
运算符:
find . \( -name '*.txt' or -name '*.pdf' \) -print # 打印所有txt和pdf文件
-path
匹配指定文件路径
find /etc/ -path '*/congf/*' -print # etc下所有包含conf的路径,打印其中的文件
-regex
与-path
类似,使用正则来匹配路径
- 否定参数
find可以使用!
来剔除指定的目标
find . ! -name '*.txt' -print # 匹配所有不是txt的文件
- 基于目录深度
-maxdepth
和-mindepth
定义搜索的深度。比如,maxdepth为1表示只在当前目录检索。
find . -maxdepth -name '*.txt' -print
由此可见,我们应该最先给出这个参数,如果放在后面可能影响find的效率。
- 基于文件类型
-type
查找指定类型的文件。在Linux中,有这几种文件:
文件类型 | 类型参数 |
---|---|
普通文件 | f |
目录文件 | d |
链接文件 | l |
字符设备 | c |
块设备 | b |
socket文件 | s |
管道文件 | p |
find . -maxdepth 1 -type f -print #当前一级目录中的普通文件
- 根据时间搜索
Linux文件系统中的文件有三个时间:
- 读取时间(
-atime
): 最近一次访问文件的时间 - 修改时间(
-mtime
): 最近一次修改文件内容的时间 - 变化时间(
-ctime
): 文件元数据(如权限和所有者)最近变更时间
+
和-
表示时间大于还是小于给定的时间,单位是天
find . -type f -atime -7 -print # 最近7天访问过的文件
find . -type f -atime 7 -print # 恰好7天前访问过的文件
find . -type f -atime +7 -print # 访问时间超过7天的文件
- 基于文件大小
-size
限定文件大小
find . -type f -size +10k # 大于10k的文件
find . -type f -size -10k #小于10k的文件
find . -typw -size 10k # 等于10k的文件
除了k
,还可以用这些:
- b ---- 块(512字节)
- c ---- 字节
- w ---- 字
- k ---- 1024字节
- M ---- 1024k
- G ---- 1024M
- find执行命令
-exec
可以说是find最强大、最灵活的特性了。
find . -type f -name '*.txt' -exec rm {} \;
这条命令删除当前目录所有txt文件。其中{}
标识find匹配到的文件名,然后送给rm执行; \;
标识结束。
下面要介绍的xargs
也可以实现这个功能
二、xargs
-
xargs
紧跟在管道之后,以标准输入作为主要数据源
多行转单行:
xargs默认使用空白作为分隔符,-d
可以指定分隔符
单行转多行:
假设有个文件存储了所有的欲下载URL,批量下载像这样:
cat url.txt | xargs wget -c
-I
选项指定替换字符串,或叫占位符,这个字符串在xargs扩展时被替换成实际内容。
cat args.txt | xargs -I {} mv {} /home/
- 结合find
find . -type f -name '*.txt' -print0 | xargs -0 rm -f
# 在这个例子里,还等价于
find . -type f -name '*.txt' -delete
之所以使用-print0
是因为有的文件名可能包含空格,如果用-print
,传给xargs的是不完整的文件名,自然找不到该文件了。而-print0
使用null分隔,更保险。
再来一例:
find . -type f -name '*.c' -print0 | xargs -0 wc -l # 统计所有C文件的行数