通过魔术模式查找文件

通过魔术模式查找文件

有一个 bash 命令文件(1),它根据 /etc/magic 和 /usr/share/misc/magic 中的匹配模式定义输出文件的内容类型。

有没有办法使用这些模式定义“魔术”文件作为“查找”命令的测试?

例如,有一些文本文件和“PalmOS应用程序”文件

file -b palmapp
PalmOS application

file -b readme.txt
ASCII text

我需要某种方法来查找与“PalmOS 应用程序”而不是“ASCII 文本”匹配的文件,例如这是一个理想的命令:

find . -magic "PalmOS*"

有没有想法为这个测试的每个文件编写一个单行 bash 命令?

答案1

大致如下:

find . -print -exec file {} \; | grep "PalmOS"

要通过 awk 整理输出管道,请添加:

| awk '{print substr($1,2,length($1)-2)}'

答案2

没有内置功能来find分析文件内容,但您可以让它调用file.使用 shell 组合多个特定于任务的程序(find遍历目录树、file分析文件内容)是 Unix 的处理方式。

您想要对命令输出file -b -- "$filename"包含字符串的文件进行操作PalmOS application。可以用shell脚本测试一下

case "$(file -b -- "$filename")" in *"PalmOS application"*) true;; *) false;; esac

find您可以在如下命令中使用此脚本:

find . -type f -exec sh -c 'case "$(file -b "$0")" in *"PalmOS application"*) true;; *) false;; esac' {} \; -print

替换-print为您要执行的操作(可以是另一个-exec …)。仅当前一个操作为 true(即 shell 命令返回 0(即 true))时,才会执行第二个操作。

或者,在 zsh 中,您可以让 shell 使用以下命令进行目录遍历**全局。这. 全局限定符将匹配限制为常规文件(例如-type ffor find)。

for x in **/*(.); do
  [[ $(file -b -- $x) = *"PalmOS application"* ]] || continue
done

在 bash ≥4.3 中,您可以使用**递归通配符,但您需要globstar先启用该选项。在 bash 4.0–4.2 中,globstar已经可用,但要注意**遍历目录的符号链接。在 ksh93 中,使用set -o globstar代替shopt -s globstar.

shopt -s globstar
for x in **/*; do
  [[ -f $x ]] || continue
  [[ $(file -b -- "$x") = *"PalmOS application"* ]] || continue
done

如果您的文件名不包含空格或任何空格,:\"'则另一种方法是在文件名上运行file并解析输出。

find -type f |
xargs file |
sed -n 's/:.*PalmOS application.*//p' |
xargs somecommand

如果您的文件名包含空格但没有换行符或冒号,那么您可以使用 shell 进行解析。

find -type f |
while IFS=: read -r filename type; do
  case "$type" in
    *"PalmOS application"*)
      …;;
  esac
done

答案3

这不使用find,而是设置pattern并将directory产生您的问题所要求的结果:

pattern="PalmOS application"
directory=.

for f in $directory/*; do
    if [[ $(file -b $f) == "$pattern" ]]; then
        echo $f; 
    fi; 
done

相关内容