0%

find命令的设计思想

find命令的设计非常棒!棒在设计理念,它把文件查找文件处理分离了。

  • 文件查找: 静态的,可预知的,可枚举的。按名字查找,名字支持正则表达式;按文件大小查找;目录递归查找。这些都是固定不变的。
  • 文件处理:动态的,不可预知的,未来会不断发展。因此设计时,find预留出了-exec回调拓展。让用户可以自定义文件处理算子,这个回调契约或说接口就仅仅是命令行。

通过find命令的演示,可以诠释架构师的价值,中台的价值。中台的意义在于面向未来业务的可拓展性,面向不可知的可拓展性。这个可拓展要在开闭原则的前提下进行。

那么find支持哪些查找条件呢?

  • 文件名查找:-name "*.png" 通配符;
  • 文件类型查找: -type f 表示文件;-type d表示目录。
  • 文件大小查找:-size +1M 表示大于1M的文件;-size -100K表示小于100K的文件。
  • 最后修改时间查找:-mmin -30 表示最后修改时间小于30分钟的;
  • 创建时间查找:-cmin -30 表示创建时间小于30分钟的。

演练样例

  • 查找1M以上的PNG文件,并逐一显示它们到底多大?
1
2
3
4
5
6
$ find . -size +1M -type f -name "*.png" -exec ls -lh  {} \;
-rw-r--r-- 1 liwei92 1603212982 1.0M 8 4 23:19 ./电子发票的耐人寻味/image-20190116140516161.png
-rw-r--r-- 1 liwei92 1603212982 1.2M 8 7 15:04 ./RPC架构层实现灰度和AOP/image-20190627133041068.png
-rw-r--r-- 1 liwei92 1603212982 1.3M 8 7 15:04 ./RPC架构层实现灰度和AOP/image-20190807141242862.png
-rw-r--r-- 1 liwei92 1603212982 1.0M 8 11 23:53 ./计数器及其应用/image-20190811234331171.png
-rw-r--r-- 1 liwei92 1603212982 1.1M 8 11 23:53 ./计数器及其应用/image-20190811124211959.png

点评: 通过-size +1M查找1M以上,通过-name "*.png"查找PNG后缀的,通过-type f只看文件。然后通过可拓展的文件处理算子 -exec 执行 ls -lh显示文件大小。

  • 查找1M以上的PNG文件,并逐一压缩? PNG文件太大,网页加载慢,需要压缩,但文件名不能变。
1
2
3
4
5
6
7
8
9
10
# 图片压缩
$ find . -size +1M -type f -name "*.png" -exec pngquant -f --ext .png {} \;

# 查看压缩效果:压缩完后,没有1M,如何找到?用最近修改时间 "-mmin -30"
$ find . -mmin -30 -type f -name "*.png" -exec ls -lh {} \;
-rw-r--r-- 1 liwei92 1603212982 286K 9 5 15:56 ./电子发票的耐人寻味/image-20190116140516161.png
-rw-r--r-- 1 liwei92 1603212982 408K 9 5 15:57 ./RPC架构层实现灰度和AOP/image-20190627133041068.png
-rw-r--r-- 1 liwei92 1603212982 371K 9 5 15:57 ./RPC架构层实现灰度和AOP/image-20190807141242862.png
-rw-r--r-- 1 liwei92 1603212982 265K 9 5 15:57 ./计数器及其应用/image-20190811234331171.png
-rw-r--r-- 1 liwei92 1603212982 411K 9 5 15:57 ./计数器及其应用/image-20190811124211959.png

点评: 图片压缩是不可预知的文件处理,只有发展到一定阶段才会有需求。但是它依然可以复用查找1M以上的PNG文件,为此我们仅仅需要开发图片压缩工具,而不用再重复开发查找工具了。

反思cpmd

当时在开发 cpmd 工具的时候,就犯了这个错误!cpmd的功能是复制markdown文件时,会连带着复制.md文件引用的图片文件。例如:

1
2
3
4
5
$ cpmd -s README.md -d backup/ -m
src file wildcard: README.md
src file list: README.md
mv assets/image-20190625115442118.png to /Users/downgoon/Documents/backup/
mv README.md to /Users/downgoon/Documents/backup/

但是使用过程中发现,复制一个文件不方便,随着积累的增多,我们需要复制多个具有某类特征的文件,比如某个目录下所有的 *.md ,为此我们却开发了对多文件的支持:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ cpmd -s 'RE*.md' -d backup/  
src file wildcard: RE*.md
src file list: README.md,REMORE.md
cp assets/image-20190625115442118.png to /Users/downgoon/Documents/backup/
cp README.md to /Users/downgoon/Documents/backup/
cp REMORE.md to /Users/downgoon/Documents/backup/

$ tree . # the two files' layout
.
├── README.md
├── REMORE.md
└── assets
└── image-20190625115442118.png

但实际上,我们完全可以复用find命令:

1
2
> $ find . -name "RE*.md" -exec cpmd -s {} -d ~/backup \;
>

其中{}表示前面查找到的文件,相当于 cpmd -s ${查找到的文件名} -d ~/backup