find: список всех каталогов, кроме номеров с именами и именами их детей

Я запускаю следующее, чтобы найти все каталоги без номера в них (не включая исходный путь):

find /path/2/directory -type d -name '[!0-9]*' 

Проблема в том, что он находит каталоги, которые являются подкаталогами каталогов, которые имеют числа.

Пример:

 /path/2/directory/20160303/backup 

или даже

 /path/2/directory/backup20160303a/backup 

Есть ли способ предотвратить поиск от таких каталогов?

Я не могу решить эту проблему, ограничивая глубину, глубина может меняться.

Пример:

 /path/2/directory/subdirectory/20160303/backup 

4 Solutions collect form web for “find: список всех каталогов, кроме номеров с именами и именами их детей”

Используйте -prune чтобы игнорировать эти каталоги:

 find /path/to/directory -name '*[0-9]*' -prune -o -type d -print 

хотя, если вы используете настройку gnu , вы можете использовать языковой стандарт C при запуске выше, см. комментарий Stéphane ниже.

Если вы не хотите, чтобы поиск происходил за определенным соответствием, вы должны использовать -prune а не eg -path или фильтровать вывод find с grep -v

Чтобы проверить ситуацию, создайте среду с некоторыми дополнительными файлами и поддиректорами, чтобы вы могли проверить свою find чтобы не отображать нежелательный материал:

 mkdir -p tmp/2/abc/def touch tmp/2/abc/def/file1 mkdir -p tmp/2/abc/9876/xyz touch tmp/2/abc/9876/xyz/file2 tree tmp/ 

дает:

 tmp └── 2 └── abc ├── 9876 │  └── xyz │  └── file2 └── def └── file1 

Если вы find tmp/2/abc \! -path "*[0-9]*" find tmp/2/abc \! -path "*[0-9]*" как было предложено @terdon, вывод будет пустым, потому что -path не просто учитывает каталоги, начинающиеся ниже abc а весь путь, который включает в себя 2 . Так что это не то, что вы хотите.

Если вы find tmp/2/abc -type d | grep -vE '/[0-9-]+(/|$)' find tmp/2/abc -type d | grep -vE '/[0-9-]+(/|$)' , как было предложено @cas, вы обнаружите, что он ничего не печатает, потому что он соответствует не только файлам, от которых вы поиск, но также каталог с именем 2 . Кроме того, для этого потребуется найти первую прогулку по всему дереву под 9876 и если там будет несколько сотен тысяч предметов, ходьба (и фильтрация) займет определенное количество времени.

Если вы это сделаете:

 find tmp/2/abc -type d -name '[!0-9]*' -print 

вы увидите, что выход включает в себя путь tmp/2/abc/9876/xyz . Чтобы избавиться от этого, -prune то, что вы не хотите с -prune : -prune :

 find tmp/2/abc -type d -name '[!0-9]*' -print -o -name '[0-9]*' -prune 

который дает:

 tmp/2/abc tmp/2/abc/def 

вы можете немного улучшить эффективность этого путем замены обрезки и печати, что и сделал @don_cristti в его усилении этого ответа.

Я думаю, что вы ищете -path :

  -path pattern File name matches shell pattern pattern. The metacharacters do not treat `/' or `.' specially; so, for example, find . -path "./sr*sc" will print an entry for a directory called `./src/misc' (if one exists). 

Он ищет весь путь для каждого файла / каталога для данного шаблона. Итак, если у вас есть такая структура каталогов:

 $ tree . ├── 111 │  └── foo │  └── bar ├── bar │  └── foo │  └── baz └── foo └── 111 └── bar 9 directories, 0 files 

Вы можете использовать find следующим образом:

 $ find /path/to/directory/ \! -path "*[0-9]*" . ./foo ./bar ./bar/foo ./bar/foo/baz 

Или, с GNU find :

 find /path/to/directory/ -not -path "*[0-9]*" 

Так как это нужно будет спуститься в каждый каталог, чтобы проверить его имя, оно будет значительно медленнее на больших деревьях каталогов, чем решение @ Anthon с черновиком. Если у вас нет тысяч каталогов, все должно быть хорошо.

Легко использовать grep (или awk или sed или perl т. Д.), Чтобы удалить такие каталоги из вывода find :

 find /path/to/directory -type d | grep -vE '/[0-9-]+(/|$)' 

Примечание. Я включил - в класс символов, потому что датированные каталоги иногда YYYY-MM-DD, а не только YYYYMMDD

  • Регулярное выражение для каждого слова, содержащего & с $ ... $
  • Сценарий Bash для копирования определенных каталогов с сопоставлением с образцом
  • Обнаружение повторения шаблонов в файле
  • Regex этот формат вопроса в LaTeX
  • Поиск специальных символов в названии
  • Извлечение IP из IP.port
  • Не совпадать ни с регулярным выражением
  • Как удалить (1) из имен файлов с помощью команды find
  • Linux sed - поиск подстановочной строки без пробелов в ней
  • Синтаксис синтаксиса «grep» для BRE или ERE содержит синтаксис «синтаксиса регулярных выражений» 8.5.6 'в справочнике findutils?
  • Выполните поиск регулярных выражений по ранее определенной линии с регулярным выражением (однострочный)
  • Тестирование RegExp с зольной оболочкой (BusyBox)
  • Linux и Unix - лучшая ОС в мире.