shell脚本学习指南[四](Arnold Robbins & Nelson H.F. Beebe著)

2019-09-23 09:42:05丽君

我们可以解决这样的一个参数过长的问题通过开始提到的xargs命令,如:
$ find /usr/include -type f | xargs grep POSIX_OPEN_MAX /dev/null
这里xargs如果未取得输入文件名,则会默认终止。GNU的xargs支持--null选项:可处理GNU find的-print0选项所产生的NUL结尾的文件名列表。xargs将每个这样的文件名作为一个完整参数,传递给它执行的命令,而没有shell(错误)解释问题或换行符号混淆的危险,然后是交给其后的命令处理它的参数。另外xargs的选项可以控制哪些参数需要被替换,还可以限制传递的参数个数等。

如果了解文件系统的空间信息,我们可以通过find和ls命令配合awk程序协助就可办到,比如:
$ find -ls | awk '{sum +=$7} END {printf("Total: %.0f bytesn",sum)}'
但并不好用,编码长不说还不知道可用空间。有两个好用的命令来解决这一需求:df和du。

df(disk free)提供单行摘要,一行显示一个加载的文件系统的已使用和可实用空间。显示单位具体看相应版本。可以实用-k强制实用kilobytes单位。还有一个选项-l 仅显示本地文件系统,排除网络加载的文件系统。还有-i选项,提供访问inode使用量。GNU的df还提供-h(human-readable)选项,方便阅读。还可以提供一个或多个文件系统名称或加载点来限制输出项目:$ df -lk /dev/sda6 /var 。

du会摘要文件系统的可用空间,但是不会告诉你某个特定的目录树需要多少空间,这是du(disk usage)的工作。不同系统可能有所不同,-k控制单位,-s显示摘要。
GNU版本提供-h,同df。du可以解决的一个常见问题是:找出哪个用户用掉最多的系统空间:$ du -s -k /home/users/* | sort -k1nr | less
假设用户目录全部放在/home/users下。

关于比较文件好用的两个命令cmp和diff。cmp直接后边跟两个文件参数即可,如果不同输出结果会指出第一个不同处的位置,相同没有任何输出。-s可以抑制输出,可以通过$?来查看离开状态码,非零表示不同。diff惯例是将旧文件作为第一个参数,不同的行会以前置左尖括号的方式,对应到左边文件,而前置右尖括号则指的是右边的文件。还有一个扩展是diff3,比较3个文件。

有时候需要修复不同的地方,patch命令提供了十分方便的做法:


$ echo test 1 > test.1
$ echo test 2 > test.2
$ diff -c test.[12] > test.dif
$ patch < test.dif

此时你查看test.1会发现里边的内容已经变为test 2了。patch会尽可能套用不同之处,然后报告失败的部分,由用户自行处理。虽然patch也可以处理一般的diff输出,但是常规都是处理diff -c选项的信息。

如果有你怀疑有很多文件有相同的内容,实用cmp或diff就十分麻烦。这时可以实用file checksum(文件校验和),取得近似线性的性能完成这一繁琐的工作。有很多工具可以提供,如:sum、cksum、checksum,消息摘要工具md5与md5sum,安全性三列(secure-hash)算法工具sha、sha1sum、sha256以及sha384。可惜的是:sum的实例在各个平台都不想同,使得他们的输出无法跨越不同unix版本进行文件校验和的比较。一般的会这样: