文件查找
在文件系统上查找符合条件的文件
文件查找: locate, find
非实时查找(数据库查找):locate
实时查找: find
locate
查询系统上预建的文件索引数据库
/var/lib/mlocate/mlocate.db
依赖于事先构建的索引
索引的构建是在系统较为空闲时自动进行(周期性任务), 管理员手动更新数据库
(updatedb)
索引构建过程需要遍历整个根文件系统, 极消耗资源
工作特点:
查找速度快
模糊查找 : 只要包含有 keyword, 不论在文件路径全名的任何部分, 都会显示出来
非实时查找
搜索的是文件的全路径, 不仅仅是文件名
可能只搜索用户具备读取和执行权限的目录
用法: locate KEYWORD
有用的选项
-i 不区分大小写的搜索
-n N 只列举前 N 个匹配项目
-r 使用基本的正则表达式
示例
搜索名称或路径中带有 "conf" 的文件
locate conf
使用 Regex 来搜索以 ".conf" 结尾的文件
locate -r '\.conf$'
注意: 不论它是用普通模式 (支持通配符) 还是正则表达式模式, 都是匹配的包含即可. 而 find 的正则表达式模式必须整个路径全部精确匹配才可
find
实时查找工具, 通过遍历指定路径完成文件查找
工作特点:
查找速度略慢
精确查找
实时查找
可能只搜索用户具备读取和执行权限的目录
语法:
find [OPTION]... [查找路径] [查找条件] [处理动作]
查找路径: 指定具体目标路径, 默认为当前目录
- 注意当查找当前目录的时候, find 显示的结果最前面不是完整路径名, 而是以./ 开头的, 如果用 regex 的时候要注意
查找条件: 指定的查找标准, 可以文件名, 大小, 类型, 权限等标准进行, 默认为找出指定路径下的所有文件
处理动作: 对符合条件的文件做操作, 默认输出至屏幕
注意: find 命令默认就递归文件夹目录了, 不需要加 - r, 可以通过下面的最大最小深度来改变默认的全部递归
注意 find -name 的时候默认支持通配符, 而 locate 查看帮助得知默认也是支持通配符(但是中括号的那种貌似不支持), 详细看 man 帮助解释
注意 find -name 匹配通配符时候要加上双引号, 同时里面的 *,?,[], 支持匹配开头带一个. 的文件了
查找条件
指搜索层级
-maxdepth level 最大搜索目录深度, 指定目录下的文件为第 1 级
-mindepth level 最小搜索目录深度
例子: find -maxdepth 1 只搜索当前目录
先处理目录内的文件, 再处理指定目录
-depth
它的结果会先显示文件, 最后再显示目录和里面的内容
根据文件名和 inode 查找:
-name "文件名称": 支持使用 glob 通配符
*, ?, [], [^]
-iname "文件名称": 不区分字母大小写
-inum n 按 inode 号查找
-samefile name 相同 inode 号的文件
-links n 链接数为 n 的文件
-regex "PATTERN" -
注意: 以 PATTERN 匹配整个文件路径, 而非文件名称. 如果只有包含这个 pattern 的文件路径, 并不能识别, 必须要整个路径全部匹配才可, 因此注意要多加.*
locate 的基本正则表达式则只需要包含即可, 注意区分, 这就是精确匹配和模糊匹配的区别
同时注意, 如果 - name 文件名 的方式, 也要多加通配符 *, 不然它也只会匹配到精确的名字, 只不过比正则表达式模式好的地方是它不需要全路径.
find 能够找到的是只有和搜索内容 yum.conf 一致的 /etc/yum.conf 文件, 而 /root/yum.conf.bak 文件虽然含有搜索关键字, 但是不会被找到
因此可以看出 find 命令是完全匹配的, 必须和搜索关键字一模一样才会列出, 可以根据不同搜索模式多加 partern, 或者 regex.
根据属主, 属组查找:
-user USERNAME: 查找属主为指定用户 (UID) 的文件
-group GRPNAME: 查找属组为指定组 (GID) 的文件
-uid UserID: 查找属主为指定的 UID 号的文件
-gid GroupID: 查找属组为指定的 GID 号的文件
-nouser: 查找没有属主的文件 : 删除了的用户创建的文件, 下同
-nogroup: 查找没有属组的文件
根据文件类型查找
-type TYPE
f: 普通文件
d: 目录文件
l: 符号链接文件
s: 套接字文件
b: 块设备文件
c: 字符设备文件
p: 管道文件
空文件或目录
-empty
示例: find /App -type d -empty
组合条件:
与:-a 默认
或:-o
非:-not !
德. 摩根定律:
(非 A) 或 (非 B) = 非(A 且 B)
(非 A) 且 (非 B) = 非(A 或 B)
示例:
- !A -a !B = !(A -o B)
- !A -o !B = !(A -a B)
find 示例
- find -name snow.PNG
- find -iname snow.PNG
- find / -name "*.txt"
- find /var -name "*log*"
- find -user joe -group joe
- find -user joe -not -group joe
- find -user joe -o -user jane
找出当前目录下属主既不是 joe 也不是 jane 的文件
- find -not \( -user joe -o -user jane \)
- find / -user joe -o -uid 500
找出 / tmp 目录下, 属主不是 root, 且文件名不以 f 开头的文件
- find /tmp \( -not -user root -a -not -name 'f*' \) -ls
- find /tmp -not \( -user root -o -name 'f*' \) -ls
注意 find 里面的小括号要转义
排除目录
示例:
查找 / etc / 下, 除 / etc/sane.d 目录的其它所有. conf 后缀的文件
find /etc -path '/etc/sane.d' -a -prune -o -name ".conf"
查找 / etc / 下, 除 / etc/sane.d 和 / etc/fonts 两个目录的所有. conf 后缀的文件
- find /etc \( -path "/etc/sane.d" -o -path "/etc/fonts" \) -a -prune -o -
- name ".conf"
注意上面的文件夹单引号或者双引号都可以, 但不能在目录后面多加一个 /, 不然结果相当于无效, 仍然会搜索这些文件夹
-a 可以不用, 还有如果用 - path 选项, 那么其后面的文件夹名称是针对 find 后面写的路径的相对路径来找的, 只有前面也是绝对路径,-path 后面再用绝对路径才有效, 详细可以看 man find 帮助
根据文件大小来查找:
-size [+|-]#UNIT
常用单位: k, M, G,c(byte)
#UNIT: (#-1, #]
如: 6k 表示(5k,6k]
-#UNIT:[0,#-1]
如:-6k 表示[0,5k]
+#UNIT:(#,∞)
如:+6k 表示(6k,∞)
根据时间戳:
以 "天" 为单位, 注意天数是往前倒着算的, 当前为 0 天
- -atime [+|-]#,
- #: [#,#+1)
- +#: [#+1,∞]
- -#: [0,#)
- -mtime
- -ctime
以 "分钟" 为单位
-amin -mmin -cmin
根据权限查找:
-perm [/|-]MODE
MODE: 精确权限匹配
/MODE: 任何一类 (u,g,o) 对象的权限中只要能一位匹配即可, 或关系,+ 从 centos7 开始淘汰
-MODE: 每一类对象都必须同时拥有指定权限, 与关系
上面的两个 MODE 中 0 表示不关注相对应的属主, 属组, 或者其它人
find -perm 755 会匹配权限模式恰好是 755 的文件
只要当任意人有写权限时, find -perm +222 就会匹配
只有当每个人都有写权限时, find -perm -222 才会匹配
只有当其它人 (other) 有写权限时, find -perm -002 才会匹配
注意: 当三位中只有一个位上有数值, 另两位都为 0 时,/ 和 - 并无区别, 因为另外两位不关注了(特殊权限也可以查询, 严格点应该有 4 位)
但是注意, 如果没有 / 或者 - 表示精确匹配的时候, 0 就是代表没有权限, 不是不关注的意思, 需要区分
处理动作
-print: 默认的处理动作, 显示至屏幕
-ls: 类似于对查找到的文件执行 "ls -l" 命令
-delete: 删除查找到的文件
-fls file: 查找到的所有文件的长格式信息保存至指定文件中, file 写的是文件名, 可以不存在它会自己创建一个
-ok COMMAND {} \; 对查找到的每个文件执行由 COMMAND 指定的命令, 对于每个文件执行命令之前, 都会交互式要求用户确认
-exec COMMAND {} \; 对查找到的每个文件执行由 COMMAND 指定的命令
{}: 用于引用查找到的文件名称自身
find 传递查找到的文件至后面指定的命令时, 查找到所有符合条件的文件一次性传递给后面的命令
参数替换 xargs
由于很多命令不支持管道 | 来传递参数, xargs 用于产生某个命令的参数
xargs 可以读入 stdin 的数据, 并且以空格符或回车符将 stdin 的数据分隔成为参数一个一个传给后面的命令
许多命令不能接受过多参数, 命令执行可能会失败, xargs 可以解决
需要注意: 文件名或者是其他意义的名词内含有空格符的情况
find 和 xargs 的组合: find | xargs COMMAND
示例:
ls | xargs rm 删除当前目录下的大量文件
find /sbin/ -perm +700 | ls -l 这个命令是错误的
find /bin/ -perm /7000 | xargs ls -Sl
查找有特殊权限的文件, 只要 3 个 sst 有一个即可
find /bin/ -perm -7000 | xargs ls -Sl
此命令和上面有何区别?
答: 查找有特殊权限的文件, 3 个特殊权限都必须拥有
find -type f -name "*.txt" -print0 | xargs -0 rm 以字符 nul 分隔, 这是针对文件名中有空格符的文件来说的
注意: nul 它并不是空字符的意思, 它是 \ 0 ascii 中第一个字符
xargs 配合进行多用户创建
xargs 后面默认隐藏了 echo, 后面不加命令的话会把前面传递进来的值显示一遍. 但是它会把前面输入的值里面的回车默认给换成空格
因为 useradd 不支持一次创建多个用户, 并且也不支持用户名之间有空格, 所以直接传递会报错, 必须用 xargs -n 1 命令让它每行只显示一个参数, 然后就换行.
这样配合这个命令便可创建多用户了.
例子:
20:11[root@centos7 /run/media/root/CentOS 7 x86_64/Packages]# seq 5 1 2 3 4 5 20:11[root@centos7 /run/media/root/CentOS 7 x86_64/Packages]# seq 5|xargs 1 2 3 4 5 echo newuser{ 1..5 } |xargs -n 1 useradd
xargs 它本身也是有一个默认换行的长度. 因为用 touch 或者 rm 命令等, 他们本身支持多个参数, 所以可以不定义 xargs 后每一行有多少个参数, 但 useradd 这种一次只能一个的, 必须定义一行一个.
用 echo {1..100000} |xargs |wc -l 可知分成 5 行
用 echo {1..100000} |xargs>f1.t , 查看 f1 , 得知一行有 23695 个参数, 这也是默认换行的每一行最多的参数, touch 等可以支持这么多的参数.
find 示例
备份配置文件, 添加. orig 这个扩展名
find -name "*.conf" -exec cp {} {}.orig \;
提示删除存在时间超过3天以上的 joe 的临时文件
find /tmp -ctime +3 -user joe -ok rm {} \;
在主目录中寻找可被其它用户写入的文件
find ~ -perm -002 -exec chmod o-w {} \;
查找 / data 下的权限为 644, 后缀为 sh 的普通文件, 增加执行权限
find /data -type f -perm 644 -name "*.sh" -exec chmod 755 {} \;
查看 / home 的目录
find /home -type d -ls
压缩, 解压缩及归档工具
file-roller compress/uncompress: .Z gzip/gunzip: .gz bzip2/bunzip2: .bz2 xz/unxz: .xz ?zip/unzip tar cpio
压缩: 牺牲 CPU 性能节省硬盘空间
compress/uncompress
compress [-dfvcVr] [-b maxbits] [file ...] , 默认删除原文件
-d 解压缩, 相当于 uncompress
-c 结果输出至标准输出, 不删除原文件 用法示例: compress -c file>file.Z
-v 显示详情
uncompress file.Z 解压缩
zcat file.Z 不显示解压缩的前提下查看文本文件内容, 相当于预览
示例: zcat file.Z>file , 这样的话也就相当于解压缩到 file 中了
注意: 如果改了文件后缀 *.Z , 则解压缩无法实施, 没有效果. 这个压缩工具对于文件后缀有要求.
gzip/gunzip
gzip [OPTION]... FILE ... 默认删除原文件
-d 解压缩, 相当于 gunzip
-c 结果输出至标准输出, 保留原文件不改变
-# 指定压缩比,# 取值为 1-9, 值越大压缩比越大
-r 可以递归压缩文件夹里面的文件, 但是是一个一个压缩成一个一个的文件, 并非是压缩成一个文件, 它不能压缩文件夹
gunzip file.gz 解压缩
zcat file.gz 不显式解压缩的前提下查看文本文件内容
示例:
gzip -c messages>messages.gz gzip -c -d messages.gz> messages zcat messages.gz> messages cat messages | gzip> m.gz lscpu |gzip> CPU.gz ; zcat cup.gz
gzip 可以对标准输出进行压缩, 比如上面的命令, 比如 MySQL 的数据库备份压缩.(其实这 4 个压缩命令都可以,)
bzip2/bunzip2/bzcat
bzip2 [OPTION]... FILE ...
-k keep, 保留原文件
-c 结果指向标准输出
-d 解压缩
-# 1-9, 压缩比, 默认为 9
bunzip2 file.bz2 解压缩
bzcat file.bz2 不显式解压缩的前提下查看文本文件内容
xz/unxz/xzcat
xz [OPTION]... FILE ...
-k keep, 保留原文件
-c 结果指向标准输出
-d 解压缩
-# 压缩比, 取值 1-9, 默认为 6
unxz file.xz 解压缩
xzcat file.xz 不显式解压缩的前提下查看文本文件内容
注意只有 gzip 才有 - r 选项, 上面 4 个都是针对文件来压缩的
zip/unzip
打包压缩
zip -r /backup/sysconfig /etc/sysconfig/
解包解压缩
unzip sysconfig.zip cat /var/log/messages | zip messages - unzip -p message> message
注意: zip -r filezip lists , 前面的是要打包并压缩成的文件, 后面的是需要被压缩的文件列表或者文件夹.
前面的文件名可以不用加上 zip 后缀, 它会自己加上, 后面的 lists 如果是文件夹, 它会把它的路径记下来, 然后解压的时候会在当前的目录里面生成这个路径(相当于把当前路径当做压缩时的路径的相对路径了, 如果压缩时写的绝对路径, 则把当前路径当做根路径)
tar 工具: 打包文件(也可顺便用三种压缩), 解包(并可顺便解压)
tar [OPTION]...
(1) 创建新归档, 保留权限(保留不住 ACL 权限, 需要单独备份), 查看过程,-f 指向归档
tar -cpvf /PATH/FILE.tar FILE...
(2) 追加文件至归档: 注: 不支持对压缩文件追加
tar -r -f /PATH/FILE.tar FILE...
(3) 查看归档文件中的文件列表
tar -t -f /PATH/FILE.tar
(4) 展开归档
tar -x -f /PATH/FILE.tar tar -x -f /PATH/FILE.tar -C(大写) /PATH/
(5) 结合压缩工具实现: 归档并压缩
-j: bzip2, -z: gzip, -J: xz
注意 -c 创建新归档,-f 指向归档, 同时用可以 , 也可以单独用 - f , 但没有单独用 - c 的.
tar 命令不看文件后缀, 可以解包解压, 修改后缀也没事
同理解压解包也会保留原文件的路径, 如果不加 - C 则会解压到当前路径, 并把当前路径当做之前压缩时写的路径的参考路径(写的绝对路径则把当前路径当做根)(它压缩的时候会删除掉最前面的 / 避免解压覆盖原文件).
-exclude 排除文件
tar zcvf /root/a3.tgz --exclude=/App/host1 --exclude=/App/host2 /App
-T 选项指定输入文件 -X 选项指定包含要排除的文件列表
tar zcvf mybackup.tgz -T /root/includefilelist -X /root/excludefilelist
split: 分割一个文件为多个文件
分割大的 tar 文件或 tar.## 压缩文件为多份小文件
split -b Size -d tar-file-name prefix-name split -b 1M -d mybackup.tgz mybackup-parts split -b 1M mybackup.tgz mybackup-parts
合并:
cat mybackup-parts*> mybackup.tar.gz
-d 选项可以用数字分每个 part
cpio : 老牌打包工具(不带压缩)
功能: 复制文件从或到归档
cpio 命令是通过重定向的方式将文件进行打包备份, 还原恢复的工具, 它可以解压以 ".cpio" 或者 ".tar" 结尾的文件
cpio [选项]> 文件名或者设备名
cpio [选项] <文件名或者设备名
注意 i 和 o 都是针对于内存来说的输入内存处理解包和内存数据输出到硬盘打包
选项
-o 将内存中的数据 (前面可用管道) 拷贝打包成文件或者将文件打包 , 默认输出到标准输出(屏幕), 可以用重定向输出到文件中(相当于 - F, 可以用 - F 代替 重定向符号<\>). 例如 ls | cpio -ov>ls.cpio
-O filename 输出到指定的归档文件名
-A 向已存在的归档文件中追加文件
-i 解包, 将打包文件解压到当前文件夹或将设备上的备份还原到系统, 可用重定向输入,(-d 可以创建文件夹)
-I filename 对指定的归档文件名解压
-t 预览, 查看打包后的文件内容列表, 可以用重新定向输入的方式, 例如 cpio -t <#### .cpio
-F filename 使用指定的文件名替代标准输入或输出
-d 解包生成目录, 在 cpio 还原时, 自动的建立目录
-v 显示打包过程中的文件名称
例子 cpio
将 etc 目录打包:
find ./etc -print |cpio -ov>bak.cpio
将 / data 内容追加 bak.cpio
find /data | cpio -oA -F bak.cpio
内容预览
cpio -t < etc.cpio
解包文件
cpio -idv < etc.cpio (解包经测试 - d 不用也可以)
file 命令可以查看文件类型, 后面直接跟文件即可
来源: http://www.bubuko.com/infodetail-2995842.html