如何按文件类型查找文件?


9

我知道我可以用查找文件findfind . -type f -name 'sunrise'。结果示例:

./sunrise
./events/sunrise
./astronomy/sunrise
./schedule/sunrise

我也知道我可以确定文件的文件类型:file sunrise。结果示例:

sunrise: PEM RSA private key

但是如何按文件类型查找文件?

例如my-find . -type f -name 'sunrise' -filetype=bash-script

./astronomy/sunrise
./schedule/sunrise

1
有没有--filetype对find命令或其他任何会告诉你的文件类型选项。唯一可以做的就是使用--exec file {} \;它,然后grep Bourne如果您正在寻找bash脚本,或者grep Perl您正在寻找Perl脚本或类似的东西,则将其插入。
Nasir Riley

Answers:


13

Unix系统上的“文件类型”是常规文件,目录,命名管道,字符特殊文件,符号链接等。这些是find可以使用其-type选项进行过滤的文件类型。

find实用程序本身无法区分“ shell脚本”,“ JPEG图像文件”或任何其他类型的常规文件。但是,file实用程序可以区分这些类型的数据,该实用程序会查看文件本身中的特定签名以确定其类型。

标记不同类型的数据文件的常用方法是通过其MIME类型,并且file能够确定文件的MIME类型。


使用filewith find来检测常规文件的MIME类型,并仅使用它来查找shell脚本:

find . -type f -exec sh -c '
    case $( file -bi "$1" ) in
        */x-shellscript*) exit 0
    esac
    exit 1' sh {} ';' -print

或者,使用bash

find . -type f \
    -exec bash -c '[[ "$( file -bi "$1" )" == */x-shellscript* ]]' bash {} ';' \
    -print

如果只希望检测具有该名称的脚本,请-name sunrise在之前添加-exec

find上面的命令将在当前目录中或当前目录下找到所有常规文件,并为每个此类文件调用一个简短的内嵌shell脚本。该脚本file -bi在找到的文件上运行,并且如果该命令的输出包含字符串,则退出状态为零/x-shellscript。如果输出不包含该字符串,则会以非零退出状态退出,这将导致find立即继续下一个文件。如果发现该文件是Shell脚本,则该find命令将继续输出文件的路径名(-print末尾的,也可以用其他操作代替)。

file -bi命令将输出文件的MIME类型。对于Linux(和大多数其他系统)上的Shell脚本,这类似于

text/x-shellscript; charset=us-ascii

而在file实用程序版本稍旧的系统上,

application/x-shellscript

公用位是/x-shellscript子字符串。

请注意,在macOS上,由于某些原因,您必须使用file -bI而不是(该选项的功能有所不同)。macOS上的输出类似于Linux系统的输出。file -bi-i


您是否想对每个找到的Shell脚本执行一些自定义操作,可以用另一个命令-exec代替上面-printfind命令中的脚本,但是也可以这样做

find . -type f -exec sh -c '
    for pathname do
        case $( file -bi "$pathname" ) in
            */x-shellscript*) ;;
            *) continue
        esac

        # some code here that acts on "$pathname"

    done' sh {} +

或者bash

find . -type f -exec bash -c '
    for pathname do
        [[ "$( file -bi "$pathname" )" != */x-shellscript* ]] && continue

        # some code here that acts on "$pathname"

    done' bash {} +

有关:


1

您可以find在每个找到的文件上执行,然后执行grep获得您感兴趣的结果。

# When looking for ASCII Text
find . -type -exec file {} \; | grep "ASCII"
# or for MS Word Documents
find . -type f -exec file {} \; | grep "Microsoft Word"

我建议使搜索模式尽可能接近您的期望,以使误报匹配的次数保持较低。

请注意,文件名中包含换行符的文件可能会导致此方法出现问题。


0

使用perlFile::LibMagic模块:

perl -MFile::LibMagic=:easy -MFile::Find -le '
  find sub {
    print $File::Find::name if
      $_ eq "sunrise" and
      -f and
      MagicFile$_ eq "PEM RSA private key"
  }, @ARGV' -- .
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.