знайти назви файлів, які НЕ закінчуються на конкретних розширеннях в Unix?


207

Чи є простий спосіб рекурсивно знайти всі файли в ієрархії каталогів, які не закінчуються у списку розширень? Наприклад, усі файли, які не є * .dll або * .exe

UNIX / GNU знаходить, такий потужний, схоже, не має excludeрежиму (або я цього не вистачає), і мені завжди було важко використовувати регулярні вирази, щоб знайти речі, які не відповідають певному виразу .

Я перебуваю в середовищі Windows (використовуючи порт GnuWin32 більшості інструментів GNU), тому я однаково відкритий для рішень, що стосуються лише Windows.

Відповіді:


343

Або без, (і від цього потрібно уникати:

find . -not -name "*.exe" -not -name "*.dll"

а також виключити перелік каталогів

find . -not -name "*.exe" -not -name "*.dll" -not -type d

або в позитивній логіці ;-)

find . -not -name "*.exe" -not -name "*.dll" -type f

6
-notможна замінити на '!'(цитата рекомендується). З іншого боку, -nameчутливий до регістру, але -inameвін нечутливий до регістру.
Іван Чау


8
$ find . -name \*.exe -o -name \*.dll -o -print

Перші параметри з двома іменами мають опцію -print, тому вони пропускаються. Все інше друкується.


4

Ви можете зробити щось за допомогою команди grep:

find . | grep -v '(dll|exe)$'

-vПрапор на grepспеціально означає «знайти речі , які НЕ відповідають цьому виразу.»


6
Grep -v '\ (длл | ехе) $. Запобігло б зіставлення againsta файлу або реж їм "Dexe", наприклад
drAlberT

Це працює лише з розширеним регулярним виразом. Мені довелося додати -E (або використовувати egrep), щоб зробити цю роботу.
Joctee

2

ще один :-)

$ ls -ltr
всього 10
-rw-r - r-- 1 скрипт linuxdumb 47 23 грудня 14:46 test1
-rw-r - r-- 1 скрипт linuxdumb 0 4 січня 23:40 test4
-rw-r - r-- 1 скрипт linuxdumb 0 4 січня 23:40 test3
-rw-r - r-- 1 скрипт linuxdumb 0 4 січня 23:40 test2
-rw-r - r-- 1 скрипт linuxdumb 0 4 січня 23:41 file5
-rw-r - r-- 1 скрипт linuxdumb 0 4 січня 23:41 file4
-rw-r - r-- 1 скрипт linuxdumb 0 4 січня 23:41 файл3
-rw-r - r-- 1 скрипт linuxdumb 0 4 січня 23:41 file2
-rw-r - r-- 1 скрипт linuxdumb 0 4 січня 23:41 file1
$ знайти. -типу f! -назви "* 1"! -ім'я "* 2" -друк
./test3
./test4
./file3
./file4
./file5
$

Unix знайти посилання команди



1

Linux / OS X:

Починаючи з поточного каталогу, рекурсивно знайдіть усі файли, що закінчуються на .dll або .exe

find . -type f | grep -P "\.dll$|\.exe$"

Починаючи з поточного каталогу, рекурсивно знайдіть усі файли, які НЕ закінчуються в .dll або .exe

find . -type f | grep -vP "\.dll$|\.exe$"

Примітки:

(1) Опція P у програмі grep вказує на те, що ми використовуємо стиль Perl для написання своїх регулярних виразів, які використовуються разом із командою grep . З метою вибору команди grep у поєднанні з регулярними виразами я вважаю, що стиль Perl - це найпотужніший стиль навколо.

(2) Опція v grep вказує оболонці виключити будь-який файл, що задовольняє регулярному вираженню

(3) Символ $ в кінці сказати ".dll $" - це символ управління роздільником, який повідомляє оболонці, що рядок імені файлу закінчується на ".dll"


0

Інші рішення на цій сторінці небажані, якщо у вас довгий список розширень - зберігаючи довгу послідовність -not -name 'this' -not -name 'that' -not -name 'other' було б втомливим та схильним до помилок - або якщо пошук є програмним, а список розширень складається під час виконання.

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

.
└── a
    ├── 1.txt
    ├── 15.xml
    ├── 8.dll
    ├── b
    │   ├── 16.xml
    │   ├── 2.txt
    │   ├── 9.dll
    │   └── c
    │       ├── 10.dll
    │       ├── 17.xml
    │       └── 3.txt
    ├── d
    │   ├── 11.dll
    │   ├── 18.xml
    │   ├── 4.txt
    │   └── e
    │       ├── 12.dll
    │       ├── 19.xml
    │       └── 5.txt
    └── f
        ├── 13.dll
        ├── 20.xml
        ├── 6.txt
        └── g
            ├── 14.dll
            ├── 21.xml
            └── 7.txt

Ви можете зробити щось подібне:

## data section, list undesired extensions here
declare -a _BADEXT=(xml dll)

## code section, this never changes
BADEXT="$( IFS="|" ; echo "${_BADEXT[*]}" | sed 's/|/\\|/g' )"
find . -type f ! -regex ".*\.\($BADEXT\)"

Результати:

./a/1.txt
./a/b/2.txt
./a/b/c/3.txt
./a/d/4.txt
./a/d/e/5.txt
./a/f/6.txt
./a/f/g/7.txt

Ви можете змінити список розширень, не змінюючи блок коду.

ПРИМІТКА не працює з рідною OSX find- використовуйте натомість gnu find.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.