有没有一种方便的方法将文件分类为“二进制”或“文本”?

有没有一种方便的方法将文件分类为“二进制”或“文本”?

标准 Unix 实用程序如grepdiff使用一些启发式方法将文件分类为“文本”或“二进制”。 (例如,grep的输出可能包括像这样的行Binary file frobozz matches。)

是否有一种方便的测试可以在zsh脚本中应用来执行类似的“文本/二进制”分类? (除了类似的东西grep '' somefile | grep -q Binary。)

(我意识到任何这样的测试都必然是启发式的,因此并不完美。)

答案1

如果您file只要求哑剧类型你会得到很多不同的,比如text/x-shellscript,等等application/x-executable,但我想如果你只检查“文本”部分,你应该会得到很好的结果。例如(-b输出中没有文件名):

file -b --mime-type filename | sed 's|/.*||'

答案2

另一种方法是isutf8使用更多实用程序收藏。

如果文件是有效的 UTF-8 或 ASCII,或者短路,则以 0 退出,-q并打印一条错误消息(以 沉默),否则以 1 退出。

答案3

如果您喜欢 GNU 使用的启发式grep,您可以使用它:

isbinary() {
  LC_MESSAGES=C grep -Hm1 '^' < "${1-$REPLY}" | grep -q '^Binary'
}

在从文件读取的第一个缓冲区中搜索 NUL 字节(对于常规文件来说是几千字节,但对于管道或套接字或某些设备(例如/dev/random)可能要少得多)。在 UTF-8 语言环境中,它还会标记不形成有效 UTF-8 字符的字节序列。它假设LC_ALL未设置为语言不是英语的内容。

${1-$REPLY}形式允许您将其用作zsh全局限定符:

ls -ld -- *(.+isbinary)

会列出二进制文件。

答案4

file有一个--mime-encoding尝试检测文件编码的选项。

 $file --mime-encoding Documents/poster2.pdf 
Documents/poster2.pdf: binary
 $file --mime-encoding projects/linux/history-torvalds/Makefile 
projects/linux/history-torvalds/Makefile: us-ascii
 $file --mime-encoding graphe.tex 
Dgraphe.tex: us-ascii
 $file --mime-encoding software.tex 
software.tex: utf-8

您可以使用file --mime-encoding | grep binary它来检测文件是否是二进制文件。它工作可靠,尽管它可能会被长文本文件中的单个无效字符混淆。

例如,我cat为以下 shell 脚本添加别名,以避免无意中打开二进制文件而破坏我的终端:

#! /bin/sh -

[ ! -t 1 ] && exec /bin/cat "$@"
for i
do
    if file --mime-encoding -- "$i" | grep -q binary
    then
        hexdump -C -- "$i"
    else
        /bin/cat -- "$i"
    fi
done

相关内容