我正在参加UNIX的入门课程,并有一个以下的作业问题:
上一个问题中有多少个文件是文本文件?文本文件是包含人类可读内容的任何文件。 (TRICK QUESTION。在文件上运行file命令,看看文件是文本文件还是二进制数据文件!如果你只计算
.txt
扩展名的文件数,你就不会得到这个问题的分数。)
上一个问题只询问了有多少常规文件,这很容易通过find . -type f | wc -l
找出。
我只是在确定“人类可读内容”是什么时遇到了问题,因为我认为它除了二进制/汇编之外还有其他内容,但我认为这是-type f
显示的内容。也许那就是教授所说的“技巧问题”?
这个问题后面有一个跟进,也问“什么文本文件包含字符串”csc“在任何大小写的混合?”。显然,“text”指的不仅仅是.txt
个文件,但我需要弄清楚第一个问题来确定这个!
答案 0 :(得分:6)
为清晰起见,增加了引号:
对文件运行“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中的含义。很多文件甚至没有文件扩展名!
我认为教授希望我们能够对所有文件运行文件命令,并计算其中包含“text”的文件数。
多部分答案怎么样?我将在#1中给出直截了当的解决方案,这可能是你的教授正在寻找的。如果你有兴趣,我会解释它的缺点以及如何改进它。
如果您已经了解了这一点,可以使用xargs
。 xargs
运行另一个命令,使用stdin中的数据作为该命令的参数。
$ 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
命令的结尾。
答案 1 :(得分:0)
有一种简单明了的方法可以确定文件是否是人类可读的文本文件,只需使用file --mime-type <filename>
并查找'text/plain'
即可。无论文件是否具有结尾或者具有与.txt不同的结尾
所以你会这样做:
FILES=`find $YOUR_DIR -type f`
for file in $FILES ;
do
mime=`/usr/bin/file --mime-type $YOUR_DIR/$file | /bin/sed 's/^.* //'`
if [ $mime = "text/plain" ]; then
fileTotal=$(( fileTotal + 1 ))
echo "$fileTotal - $file"
fi
done
echo "$fileTotal human readable files found!"
输出就像:
1 - /sampledir/samplefile
2 - /sampledir/anothersamplefile
....
23 human readable files found!
如果您想进一步了解更多人类可读的mime类型(例如,HTML和/或XML计数?),请查看http://www.feedforall.com/mime-types.htm