Як знайти файли за типом файлу?


9

Я знаю , що можу знайти файли з допомогою find: find . -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

Відповіді:


13

"Типи файлів" в системі Unix - це такі речі, як звичайні файли, каталоги, названі труби, спеціальні файли символів, символічні посилання тощо. Це тип файлів, які findможна фільтрувати за допомогою своєї -typeопції.

findУтиліта не може сам по собі відмінності між «сценарієм оболонкою», «файлом зображення JPEG» або будь-яким іншим типом звичайного файлу . Ці типи даних, однак, можуть відрізнятися fileутилітою, яка розглядає конкретні підписи в самих файлах, щоб визначити їх тип.

Поширений спосіб позначити різні типи файлів даних - це їх тип MIME , і fileвін може визначити тип файлу MIME.


Використовуйте fileдля, findщоб виявити звичайні файли типу MIME, і використовуйте їх лише для пошуку скриптів оболонки:

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Вище команда знайде всі звичайні файли або нижче поточного каталогу, і для кожного такого виклику файлу короткого замикання в лінії сценарію оболонки. Цей скрипт працює file -biна знайденому файлі і виходить із нульовим статусом виходу, якщо вихід цієї команди містить рядок /x-shellscript. Якщо висновок не містить цього рядка, він закінчується з ненульовим статусом виходу, що змушує findнегайно продовжувати наступний файл. Якщо файл знайшов сценарій оболонки, findкоманда перейде до виводу імені файлу ( -printв кінці, який також може бути замінений деякою іншою дією).

file -biКоманда буде виводити тип MIME файлу. Для сценарію оболонки в Linux (і більшості інших систем) це було б щось подібне

text/x-shellscript; charset=us-ascii

тоді як на системах з дещо старшим варіантом fileутиліти це може бути

application/x-shellscript

Загальний біт - це /x-shellscriptпідрядка.

Зверніть увагу , що на MacOS, ви повинні використовувати file -bIзамість file -biз причин ( -iваріант робить щось зовсім інше). Вихід на macOS аналогічний результатам роботи системи Linux.


Ви хотіли б , щоб виконати деякі призначені для користувача дії на кожному сценарії оболонки Found, ви могли б зробити це з іншого -execна місці -printв findкомандах вище, але також було б можливо зробити

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кожен знайдений файл, а потім отримати греп за результат, який вас цікавить.

# 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

Використання perl«s File::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' -- .
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.