Знайдіть усі PDF-файли з принаймні трьома символами на їх ім’я


9

Я хотів би знайти файли PDF, ім’я яких (крім розширення) більше трьох.

$ find ~ -iregex ".{3,}/.pdf"

нічого не повертає, але

$ find ~ -iregex ".+/.pdf"

працює.

Як я можу включити {3,}варіант?


Яка довжина? Довжина файлу? Довжина сторінки?
Ігнасіо Васкес-Абрамс

Відповіді:


18

Припустимо, що ви використовуєте GNU find(який ви, мабуть, є, оскільки -iregexце розширення GNU до POSIXfind ), -regexа -iregexза замовчуванням - регулярні вирази Emacs, які не розпізнаються {3,}. Вам потрібно вказати інший тип регулярних виразів за допомогою -regextypeпараметра; окрім того, вам потрібно скорегувати регулярний вираз на те, що вираз відповідає повній стежці:

find ~ -regextype posix-extended -iregex '.*/[^/]{3,}.pdf'

Ви також повинні уникати .так, щоб він відповідав "." а не будь-який персонаж:

find ~ -regextype posix-extended -iregex '.*/[^/]{3,}\.pdf'

Регулярний вираз може бути спрощений, оскільки ми дбаємо лише про три не "/" символи:

find ~ -regextype posix-extended -iregex '.*[^/]{3}\.pdf'

Для повноти, з FreeBSD або NetBSD find(інша реалізація, яка підтримує -iregex, не ваша, хоча як .+би там не працювали -E), ви напишете:

find ~ -iregex '.*[^/]\{3\}\.pdf'

або:

find -E ~ -iregex '.*[^/]{3}\.pdf'

Без -Eцього - основний регулярний вираз (як в grep) і з -E розширеним регулярним виразом (як в grep -E).

З аст-відкритом find:

find ~ -iregex '.*[^/]{3}\.pdf'

(це розширені регулярні вирази поза коробкою).


20

Тут простіше зі стандартними символами:

find ~ -name '*???.[pP][dD][fF]'

Або з деякими findреалізаціями (тими, які -regexтакож підтримують -iname):

find ~ -iname '*???.pdf'

Для довільної кількості символів замість 3цього ви можете скористатися поверненням, -iregexде це можливо (див. Відповідь @Stephen Kitt ) або ви можете використовувати zshабо ksh93глобуси:

  • zsh:

    set -o extendedglob # best in ~/.zshrc
    printf '%s\n' ~/**/?(#c3,).(#i)pdf(D)
    

    ( (D)розглянути приховані файли та файли в прихованих режимах, як і з find)

    • (#cx,y)- це zshеквівалент підстановочного символу{x,y}
    • (#i) для корпусу нечутливий
    • ?стандартний підстановочний знак для будь-якого окремого символу (наприклад, regexp .)
    • **/: будь-який рівень підкаталогів (включаючи 0)
  • ksh93:

    FIGNORE='@(.|..)' # to consider hidden files
    set -o globstar
    printf '%s\n' **/{3,}(?).~(i:pdf)
    
    • @(x|y): розширений оператор wildcard ksh схожий на regexp (x|y).
    • FIGNORE: спеціальна змінна, яка контролює, які файли ігноруються глобусами. Якщо встановлено, звичайне ігнорування прихованих файлів не робиться, але ми все ще хочемо ігнорувати записи .та ..записи каталогів, де вони є.
    • {x,y}(z)є ksh93еквівалентом регулярного вираження z{x,y}.
    • ~(i:...): невідчутне до регістру відповідність.

Глобуси мають тут деякі додаткові переваги findв тому, що ви отримуєте відсортований список (ви можете відключити це сортування за zshдопомогою oNкласифікатора глобусу або використовувати різні критерії сортування), а також працювати, коли назви файлів містять послідовність байтів, які не утворюють дійсних символів (для Наприклад, у локалі, що використовує схему UTF-8, findпідхід не зможе повідомити про $'St\xE9phane Chazelas - CV.pdfте, \xE9що те, що не є символом, не відповідає зі знаком регулярного вираження .або символом підстановки ?або *з GNU find).


Це би спрацювало для Баша? shopt -s dotglob globstar; printf '%s\n' ~/**/*???.[pP][dD][fF]
wjandrea

7

Як дізнатися, що вони PDF-файли?

Ви цього не зробите, якщо не запитаєте. Звичайно, я буду педантичним, але ви не питали про файли з .pdfїх іменами . Просто тому, що у файлі є символи, .pdfім'я файлу не робить його PDF-файлом .

Насправді, будьмо всебічно педантичними щодо цього: якщо останні чотири символи імені файлу є .pdf, то у його імені завжди буде більше трьох символів .

Отже, роблячи це неправильно , ви можете сказати:

$ find . -type f -name "*???.pdf"
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Setup_MagicISO.exe.pdf

Бачите цю другу? Це насправді виконуваний файл. (Я знаю, я змінив назву.) А також мені не вистачає PDF, на який я міг присягнути, що знаходився в каталозі Документи ...

$ ls Documents
McLaren 720s Coupe:Order Summary.pdf
Pioneer Premier DEH-P490IB CD Install Manual.PDF
Setup_MagicISO.exe.pdf

Тож за допомогою -inameми могли знайти цей, але це все-таки з'являється цей файл без формату PDF.

Що ми дійсно хочемо зробити в цьому випадку - це вивчити магічне число файлу за допомогою fileкоманди. Один варіант виводить тип MIME , який простіше розбирати. Потім findзапит стає простим -name "???*".

$ find . -type f -name "???*" -print0|xargs -0 file --mime
./.bash_history:                                              text/plain; charset=us-ascii
./.bash_logout:                                               text/plain; charset=us-ascii
./.bashrc:                                                    text/plain; charset=us-ascii
./.profile:                                                   text/plain; charset=us-ascii
./Documents/McLaren 720s Coupe:Order Summary.pdf:             application/pdf; charset=binary
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF: application/pdf; charset=binary
./Documents/Setup_MagicISO.exe.pdf:                           application/x-dosexec; charset=binary
./Downloads/Setup_MagicISO.exe:                               application/x-dosexec; charset=binary
./Downloads/WindowsUpdate.diagcab:                            application/vnd.ms-cab-compressed; charset=binary

Давайте скористаємося роздільником двокрапки та шукаємо тип MIME application/pdf, а потім нульову частину викреслюємо та друкуємо результат. Візьміть на замітку, в одному з моїх файлів є двокрапка у назві; тому я не можу просто попросити awk ($2==":"){print $1}.

$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF

Тепер закінчимо, намагаючись включити PDF-файли з назвою aта abc:

$ mkdir Documents/other
$ cp -a Documents/McLaren\ 720s\ Coupe\:Order\ Summary.pdf Documents/other/a
$ cp -a Documents/Pioneer\ Premier\ DEH-P490IB\ CD\ Install\ Manual.PDF  Documents/other/abc
$ find . -type f -name "???*" -print0|xargs -0 file --mime|awk -F: '($NF~"application/pdf"){OFS=":";$NF="";print}'|sed s/:$//
./Documents/McLaren 720s Coupe:Order Summary.pdf
./Documents/Pioneer Premier DEH-P490IB CD Install Manual.PDF
./Documents/other/abc

Це все. Я знаю, що я, мабуть, примружуюсь за те, що я жахливо педантичний, але в моїй роботі з тисячами томів NFS для полювання та всіляких файлів з поганою назвою я б хотів, щоб більше людей були педантичними.

Відредаговано, щоб додати: у реальному світі я можу захотіти скористатись updatedbдля створення індексу файлу, який можна шукати, locateзамість того, findщоб читати цей індекс, а parallelне для того, xargsщоб вводити його. Це дещо поза сферою цього питання. Я це написав і з прямим обличчям. Чому я так дбаю? Я, можливо, шукаю фільми та аудіофайли; або певні типи фотографій; або двійкові виконувані файли в каталозі даних проекту.


1
Якщо у запитувача трапляється така ж ситуація, що і у вас, де є файли PDF, імена яких не закінчуються .pdf, ваша педантичність буде дуже вдячна. Але це відносно незвична ситуація (незважаючи на вашу роботу), і ми не маємо жодних підстав вважати, що запитувач насправді має справу з цим, тому я вважаю, що справа, яку ви робите, хоча є дійсною, є дещо відволікаючою - і я думаю, що насильницький спосіб, який ви це виклали, штовхає відповідь у сферу "(мабуть) не корисного". (Моя думка, звичайно.)
David Z

Оскільки ми ведемо педантичність, як би ви обробляли такі PDF-файли, як поліглоти PoC || GTFO ?
Стівен Кітт

@StephenKitt - Не впевнений, що ти запитуєш, але мене заінтригує. Вони схожі на звичайні PDF-файли для мене з не особливо прикольними назвами. Чи не вдасться це запропонувати моє запропоноване рішення?
Багатий

@DavidZ Я не впевнений, що на це сказати. Я маю на увазі, хіба це не трохи педантично зазначити, що я педантичний, коли я вже так багато сказав? Ось чому це не "корисно": хорошим рішенням для пошуку PDF-файлів має бути адаптоване рішення для пошуку скриптів, бінарних виконуваних файлів, бібліотек, медіа-файлів тощо. Я навіть не можу почати бачити, як я адаптував би один із інші відповіді на "стиснуті виконавчі файли Mach", але я готовий дізнатися.
Багатий

1
@ Багато хто з PDF-файлів - це також ZIP-файли, деякі - також зображення, або навіть завантажувальні віртуальні машини ... (Підказки див. За посиланнями "спойлери" в перших кількох випусках; решта задокументована в самих PDF-файлах.)
Стівен Кітт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.