为了清楚起见,添加了引号:
对文件运行“file”命令,查看该文件是文本文件还是二进制数据文件!
该file
命令将检查文件并告诉您它们看起来是什么类型的文件。“文本”一词将(几乎)始终出现在文本文件的描述中。
例如:
desktop.ini: Little-endian UTF-16 Unicode text, with CRLF, CR line terminators
tw2-wasteland.jpg: JPEG image data, JFIF standard 1.02
所以第一部分是要求你运行file
命令并解析它的输出。
我只是无法确定“人类可读的内容”是什么,因为我假设它意味着除了二进制/汇编之外的任何东西,但我认为这就是 -type f 显示的内容。
find -type f
查找文件。它过滤掉其他文件系统对象,如目录、符号链接和套接字。但是,它将匹配任何类型的文件:二进制文件、文本文件等。
也许这就是教授所说的“技巧问题”的意思?
听起来他只是在说不要做find -name '*.txt'
或一些类似的命令来查找文本文件。不要假设特定的文件扩展名。文件扩展名在 UNIX 中的意义远小于在 Windows 中的意义。很多文件甚至没有文件扩展名!
我在想教授希望我们能够对所有文件运行文件命令并计算其中包含“文本”的文件的数量。
多部分答案怎么样?我将在#1 中给出简单的解决方案,这可能是您的教授正在寻找的。如果您有兴趣,我会解释它的缺点以及如何改进它。
一种方法是使用xargs
,如果您已经了解的话。xargs
运行另一个命令,使用来自标准输入的数据作为该命令的参数。
$ find . -type f | xargs file
./netbeans-6.7.1.desktop: ASCII text
./VMWare.desktop: a /usr/bin/env xdg-open script text executable
./VMWare: cannot open `./VMWare' (No such file or directory)
(copy).desktop: cannot open `(copy).desktop' (No such file or directory)
./Eclipse.desktop: a /usr/bin/env xdg-open script text executable
这样可行。有点。对于家庭作业来说已经足够了。但对于现实世界的脚本来说还不够好。
注意它是如何破坏文件的VMWare (copy).desktop
,因为它有一个空格。这是由于xargs
' 在空格上拆分参数的默认行为。我们可以通过使用xargs -0
在 NUL 字符而不是空格上拆分命令参数来解决此问题。文件名不能包含 NUL 字符,因此这将能够处理任何内容。
$ find . -type f -print0 | xargs -0 file
./netbeans-6.7.1.desktop: ASCII text
./VMWare.desktop: a /usr/bin/env xdg-open script text executable
./VMWare (copy).desktop: a /usr/bin/env xdg-open script text executable
./Eclipse.desktop: a /usr/bin/env xdg-open script text executable
这对于制作脚本来说已经足够好了,而且您会经常遇到这种情况。但我个人更喜欢不需要管道的替代语法,因此效率更高。
$ find . -type f -exec file {} \;
./netbeans-6.7.1.desktop: ASCII text
./VMWare.desktop: a /usr/bin/env xdg-open script text executable
./VMWare (copy).desktop: a /usr/bin/env xdg-open script text executable
./Eclipse.desktop: a /usr/bin/env xdg-open script text executable
要理解这一点,请反复-exec
调用,用它找到的每个文件名替换。分号表示命令的结束。file
{}
\;
file