Shell 学习笔记 0x02

Shell 学习笔记 0x02

RayAlto OP

1. find

1
2
$ find ~world -name '*kindness*' | wc -l
0

1.1. -type

参数含义
bBlock 块设备
cCharacter 字符设备
dDirectory 目录
fFile 普通文件
lLink 符号链接

1.2. -size

参数含义
+1b大于 512B
+1c大于 1B
-1w小于 1 word
-1k小于 1kB
+1M大于 1MB
+1G大于 1GB

1.3. 其他实用参数

参数含义
-cmin n文件状态的最后修改时间在 n 分钟前
-mmin n文件内容的最后修改时间在 n 分钟前
-cnewer file文件状态的最后修改时间晚于 file
-newer file文件内容的最后修改时间晚于 file
-ctime n文件状态的最后修改时间在 n 天前
-mtime n文件内容的最后修改时间在 n 天前
-empty空文件或目录
-group name属于 name 组的文件或目录
-nogroup name不属于一个有效组的文件或目录
-user name属于 name 用户的文件或目录
-nouser name不属于一个有效用户的文件或目录
-iname patternIgnore Case 的 -name
-inum ninode number 为 n
-perm mode权限设置为 mode

1.4. 逻辑

find 也支持逻辑运算符来进行更复杂的匹配,常见的比如 -and, -or, -not, () ,比如查找没有 g+w 权限的:

1
find ./ -type f -and -not -perms -g+w

在比如寻找不以 jpg 结尾的文件或不以 jpg 开头的目录

1
find ./ '(' -type f -not -name '*jpg' ')' -or '(' -type d -not -name 'jpg*' ')'

1.5. 预定义的操作

find 还有一些预定义的操作可以应用到被找到的文件

参数含义
-delete删除匹配的文件
-ls对匹配的文件执行 ls -dils
-print打印全路径
-quit找到第一个匹配的之后就退出

比如删除所有以 BAK 结尾的文件:

1
find ./ -type f -name '*BAK' -delete

1.6. 自定义操作

find 也可以用 -exec 参数自定义对匹配的文件的操作,比如模仿 -delete 参数:

1
find ./ -exec rm '{}' ';'

还可以用 -ok 参数使 find 执行操作之前进行询问:

1
2
3
4
5
6
7
$ ls
foo bar
$ find ./ -type f -ok rm '{}' ';'
< rm ... ./bar > ? n
< rm ... ./foo > ? y
$ ls
bar

末尾的 ; 表示对每个匹配项分开执行定义的操作,还可以用 + 表示把所有匹配项放在一起执行定义的操作:

1
2
3
4
5
$ find ./ -type f -exec echo '{}' ';'
./bar
./foo
$ find ./ -type f -exec echo '{}' '+'
./bar ./foo

1.7. xargs

无论什么操作系统,支持参数的个数都是有限制的,如果 find 的匹配项超过了最多参数限制, -exec 就会失败,这时可以用 xargs 来处理:

1
find ./ -type f -print | xargs ls -l

xargs 会分批执行这些参数

但 Unix 下文件名甚至可以包含换行符,这样会导致 xargs 分割不准,可以通过 find-print0 使 find\0 分割文件名;再使用 xargs-0/--null 参数使 xargs 通过 \0 分割文件名:

1
find ./ -type f -print0 | xargs -0 ls -l

2. gzip

1
2
3
4
5
6
7
gzip file             # 把 file 压缩成 file.gz 并删除 file
gzip -k file # --keep 在上面的基础上保留 file
gzip -c file > foo.gz # -c 输出到 stdout , > 输出到文件,实现对输出文件的命名
gzip -9 file # 压缩,使用最大压缩率(最慢),可用值: 1-9
gzip -d file.gz # 解压, gunzip 的本质
gzip -cd file.gz # 解压并输出到 stdout , zcat 的本质, zless 也差不多
command | gzip > f.gz # 压缩命令的输出到 f.gz

其他实用选项:

选项含义
-f, --force覆盖
-l, --list列出每个文件的压缩信息
-r, --recursive递归压缩目录下的所有文件
-t, --test测试压缩文件的完整性

还有一个 bzip2 使用不同的压缩算法( gzip 使用 ZIP 用于压缩时的同款 LZ77 , bzip2 使用 BWT ),用压缩时间换取更高的压缩率,用法与 gzip 差不多

3. tar

选项含义
ccreate
ffile
zgzip compress
aauto compress
rappend
xextract
vverbose
1
2
3
4
5
6
tar cf foobar.tar foo bar           # 把 foo 和 bar 放进 foobar.tar 里
tar czf foobar.tar.gz foo bar # 在上面的基础上使用 gzip 压缩
tar caf foobar.tar.xz foo bar # tar 的基础上根据后缀选择压缩程序
tar rf foobar.tar baz # 在 foobar.tar 后面追加 baz 文件
tar xf foobar.tar.gz --directory=./ # 把 foobar.tar.gz 释放到 ./ 目录
tar tvf foobar.tar # 详细列出 foobar.tar 的内容

4. zip

1
2
3
4
5
zip -r foo.zip file ./dir  # 把 file 文件和 ./dir 目录压缩成 foo.zip
unzip foo.zip # 解压
command | zip stdout.zip - # 把输出压缩成 stdout.zip
unzip stdout.zip -p # 把刚刚输出的 stdout.zip 里的内容输出到 stdout
unzip -l foo.zip # 列出 foo.zip 里的内容

5. rsync

我常用的选项是:

  • a: archive ,等于 recursive, links, preserve permissions, preserve modification time, preserve group, preserve owner, devices, specials
  • v: verbose ,显示详细信息
  • h: human readable ,人性化
  • c: checksum ,有时需要 rsync 一些生成的文本文件,用 checksum 可以避免传输只是修改时间变了的文件
  • P: progress & partial