bash - 如何计算 Bash 中所有人类可读的文件?

标签 bash file unix human-readable

我正在学习 UNIX 入门类(class),有一个家庭作业问题如下:

How many files in the previous question are text files? A text file is any file containing human-readable content. (TRICK QUESTION. Run the file command on a file to see whether the file is a text file or a binary data file! If you simply count the number of files with the .txt extension you will get no points for this question.)

上一个问题只是询问有多少常规文件,通过执行 find 很容易弄清楚。 -类型f | wc -l.

我只是无法确定“人类可读内容”是什么,因为我假设它意味着除二进制/汇编之外的任何东西,但我认为这就是 -type f 显示的内容。也许这就是教授所说的“trick question”的意思?

这个问题后面有一个跟进,它还询问“哪些文本文件包含大小写混合的字符串“csc”?”。显然“文本”指的不仅仅是 .txt 文件,但我需要弄清楚第一个问题才能确定这一点!

最佳答案

为清楚起见添加引号:

Run the "file" command on a file to see whether the file is a text file or a binary data 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 命令并解析其输出。

I'm just having trouble determining what "human readable content" is, since I'm assuming it means anything besides binary/assembly, but I thought that's what -type f displays.

find -type f 查找文件。它过滤掉其他文件系统对象,如目录、符号链接(symbolic link)和套接字。不过,它会匹配任何类型的文件:二进制文件、文本文件等等。

Maybe that's what the professor meant by saying "trick question"?

听起来他只是在说不要执行 find -name '*.txt' 或类似的命令来查找文本文件。不要假定特定的文件扩展名。文件扩展名在 UNIX 中的意义远不如在 Windows 中的意义。许多文件甚至没有文件扩展名!


I'm thinking the professor wants us to be able to run the file command on all files and count the number of ones with 'text' in it.

多部分答案怎么样?我将在 #1 中给出直接的解决方案,这可能是您的教授正在寻找的。如果您有兴趣,我会解释它的缺点以及您可以如何改进它。

  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
    
  2. 有效。有点。这对于家庭作业来说已经足够了。但对于真实世界的脚本来说还不够好。

    请注意它是如何在文件 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
    
  3. 这对于制作脚本来说已经足够好了,而且您会经常遇到这种情况。但我个人更喜欢不需要管道的替代语法,因此效率稍微高一些。

    $ 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 命令的结束。

关于bash - 如何计算 Bash 中所有人类可读的文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12654026/

相关文章:

linux - 将输出发送到另一个命令

java - 当我输入 "java -version"时,它从哪里提取该信息?

java - 有没有办法在不使用文件扩展名的情况下识别 java 中的音频或图像文件?

java - 访问具有名称的文件的正确方法

C 编程 - 编写可自行编译的文本文件

linux - 符号表示法中的 unix 权限转换器(包括粘性位)

linux - 使用 sed 或 awk 提取两个单词之间的数据

bash - 寻找 shell 重定向交错行为的解释

database - 删除包含在命令行上传递的参数的文件中的行

linux - 为什么我的程序在安装在 Linux 中的 NTFS 分区上运行时,其核心转储始终为零字节?