有没有办法找到只包含非打印字符的文件?

jos*_*ain 6 find special-characters search binary

我有一个运行不良的程序,并且创建了许多只有几个非打印字符的文件。如果我要对文件进行分类,我什么也看不到(因为它们是非打印字符)。但是,这些文件不会显示出来,如果我使用类似-empty-size 0find命令。

有谁知道一种搜索仅包含非打印字符的文件的方法?

Gil*_*il' 9

使用 GNU grep(以及其他几个 grep 实现),您可以搜索不包含任何可打印字符的文件。该-L选项表示列出不包含匹配项的文件。[[:print:]](是的,有两对括号)匹配一个可打印字符;可打印字符的定义取决于您的语言环境。

grep -L '[[:print:]]' -- *
Run Code Online (Sandbox Code Playgroud)

请注意,这包括空文件(如Mindas 指出的)。

将它们全部删除(grep首先查看输出以确保删除正确的文件),假设文件名不包含任何换行符:

grep -L '[[:print:]]' -- * |
while IFS= read -r filename; do
  if [ -f "$filename" ] && [ -s "$filename" ]; then
    rm "$filename"
  fi
done
Run Code Online (Sandbox Code Playgroud)

或等效地(请注意,这也会删除空文件)

set +f; IFS='
' # split at newlines, turn off globbing
rm -- $(set -f; grep -L '[[:print:]]' -- *)
set -f; unset IFS
Run Code Online (Sandbox Code Playgroud)

请注意,如果当前目录中有子目录,上面的命令将产生错误消息(因为您将调用rm一个目录——不要调用rm -r!)。在 zsh 中,可以使用*(.L+0)而不是*只匹配常规的非空文件,并且不需要担心文件名中的特殊字符(换行符除外):

IFS=$'\n'
rm -- $(grep -L '[[:print:]]' -- *(.))
unset IFS
Run Code Online (Sandbox Code Playgroud)

仅使用 POSIX 工具,grep -l '[[:print:]]' -- *显示您要保留的文件(空文件除外)。

或者您可以遍历文件;这更清楚,并且肯定不会对特殊字符造成任何麻烦(但跳过点文件),但理论上(但可能无法测量)更慢。

for x in *; do
  if [ -f "$x" ] && [ -s "$x" ] && ! grep -q '[[:print:]]' <"$x"; then
    rm -- "$x"
  fi
done
Run Code Online (Sandbox Code Playgroud)