it-swarm.com.ru

Как исключить каталог в find. команда

Я пытаюсь запустить команду find для всех файлов JavaScript, но как исключить конкретный каталог?

Вот код find, который мы используем.

for file in $(find . -name '*.js')
do 
  Java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file
done
1132
helion3

Используйте переключатель Prune, например, если вы хотите исключить каталог misc, просто добавьте -path ./misc -Prune -o в команду find:

find . -path ./misc -Prune -o -name '*.txt' -print

Вот пример с несколькими каталогами:

find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -Prune -o -print

Здесь мы исключаем dir1, dir2 и dir3, поскольку в выражениях find это действие, которое действует по критерию -path dir1 -o -path dir2 -o -path dir3 (если dir1 или dir2 или dir3), а также с type -d. Дальнейшее действие - -o print, просто напечатайте.

875
f10bit

Если -Prune не работает для вас, это будет:

find -name "*.js" -not -path "./directory/*"

Caveat: требует обхода всех нежелательных каталогов.

1743
GetFree

Я считаю, что следующее легче рассуждать, чем другие предлагаемые решения:

find build -not \( -path build/external -Prune \) -name \*.js
# you can also exclude multiple paths
find build -not \( -path build/external -Prune \) -not \( -path build/blog -Prune \) -name \*.js

Важное примечание: пути, которые вы вводите после -path, должны точно соответствовать тому, что find будет печатать без исключения. Если это предложение сбивает вас с толку, убедитесь, что вы используете полные пути через целую команду, например так: find/ full/path / = -not \( -path/ полный/путь/исключить/это-Prune .... Смотрите примечание [1], если вы хотите лучшего понимания.

Внутри \( и \) находится выражение, которое будет точно соответствовать build/external (см. Важное примечание выше) и, в случае успеха, избегайте обхода чего-либо ниже . Затем он группируется как одно выражение с экранированной круглой скобкой и начинается с префикса -not, что заставит find пропускать все, что соответствует этому выражению.

Кто-то может спросить, не добавит ли -not все остальные файлы, скрытые -Prune, и ответ будет отрицательным. Способ работы -Prune состоит в том, что все, что, когда оно достигнуто, файлы в этом каталоге постоянно игнорируются.

Это происходит из реального случая использования, когда мне нужно было вызвать yui-compressor для некоторых файлов, сгенерированных wintersmith, но исключить другие файлы, которые нужно отправить как есть.


Примечание [1]: Если вы хотите исключить /tmp/foo/bar, и вы запускаете find наподобие этого "find /tmp \(...", то вы должны указать -path /tmp/foo/bar. Если, с другой стороны, вы запускаете find как этот cd /tmp; find . \(..., то вы должны указать -path ./foo/bar.

412
Daniel C. Sobral

Здесь явно есть некоторая путаница относительно того, каким должен быть предпочтительный синтаксис для пропуска каталога.

Мнение GNU

To ignore a directory and the files under it, use -Prune

На странице справки GNU find

Рассуждения

-Prune останавливает find от перехода в каталог. Просто указав -not -path, вы все равно попадете в пропущенный каталог, но -not -path будет иметь значение false, когда find проверяет каждый файл.

Проблемы с -Prune

-Prune делает то, для чего он предназначен, но все же есть некоторые вещи, о которых вы должны позаботиться, используя его.

  1. find печатает сокращенный каталог.

    • TRUE Это намеченное поведение, оно просто не опускается в него. Чтобы вообще не печатать каталог, используйте синтаксис, который логически его опускает.
  2. -Prune работает только с -print и никакими другими действиями.

    • НЕ ИСТИНА . -Prune работает с любым действием, кроме -delete. Почему это не работает с delete? Чтобы -delete работал, find должен пройти по каталогу в порядке DFS, так как -delete сначала удалит листья, затем родители листьев, и т.д ... Но для того, чтобы указать -Prune, чтобы иметь смысл, find должен попасть в каталог и прекратить его убывание, что явно не имеет смысла, если включены -depth или -delete.

Производительность

Я установил простой тест из трех самых популярных ответов на этот вопрос (заменил -print на -exec bash -c 'echo $0' {} \;, чтобы показать другой пример действия). Результаты ниже

----------------------------------------------
# of files/dirs in level one directories
.performance_test/Prune_me     702702    
.performance_test/other        2         
----------------------------------------------

> find ".performance_test" -path ".performance_test/Prune_me" -Prune -o -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 23513814

> find ".performance_test" -not \( -path ".performance_test/Prune_me" -Prune \) -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 10670141

> find ".performance_test" -not -path ".performance_test/Prune_me*" -exec bash -c 'echo "$0"' {} \;
.performance_test
.performance_test/other
.performance_test/other/foo
  [# of files] 3 [Runtime(ns)] 864843145

Заключение

Оба синтаксис f10bit и синтаксис Даниэля С. Собрала в среднем работали 10-25 мс синтаксис GetFree , который не использует -Prune, занял 865 мс. Так что, да, это довольно экстремальный пример, но если вы заботитесь о времени выполнения и делаете что-то дистанционно, вы должны использовать -Prune.

Примечание синтаксис Даниэля С. Собрала выполнил лучший из двух синтаксисов -Prune; но я сильно подозреваю, что это результат некоторого кеширования, так как переключение порядка, в котором выполнялись два процесса, приводило к противоположному результату, в то время как версия без Prune всегда была самой медленной.

Тестовый скрипт

#!/bin/bash

dir='.performance_test'

setup() {
  mkdir "$dir" || exit 1
  mkdir -p "$dir/Prune_me/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/w/x/y/z" \
    "$dir/other"

  find "$dir/Prune_me" -depth -type d -exec mkdir '{}'/{A..Z} \;
  find "$dir/Prune_me" -type d -exec touch '{}'/{1..1000} \;
  touch "$dir/other/foo"
}

cleanup() {
  rm -rf "$dir"
}

stats() {
  for file in "$dir"/*; do
    if [[ -d "$file" ]]; then
      count=$(find "$file" | wc -l)
      printf "%-30s %-10s\n" "$file" "$count"
    fi
  done
}

name1() {
  find "$dir" -path "$dir/Prune_me" -Prune -o -exec bash -c 'echo "$0"'  {} \;
}

name2() {
  find "$dir" -not \( -path "$dir/Prune_me" -Prune \) -exec bash -c 'echo "$0"' {} \;
}

name3() {
  find "$dir" -not -path "$dir/Prune_me*" -exec bash -c 'echo "$0"' {} \;
}

printf "Setting up test files...\n\n"
setup
echo "----------------------------------------------"
echo "# of files/dirs in level one directories"
stats | sort -k 2 -n -r
echo "----------------------------------------------"

printf "\nRunning performance test...\n\n"

echo \> find \""$dir"\" -path \""$dir/Prune_me"\" -Prune -o -exec bash -c \'echo \"\$0\"\'  {} \\\;
name1
s=$(date +%s%N)
name1_num=$(name1 | wc -l)
e=$(date +%s%N)
name1_perf=$((e-s))
printf "  [# of files] $name1_num [Runtime(ns)] $name1_perf\n\n"

echo \> find \""$dir"\" -not \\\( -path \""$dir/Prune_me"\" -Prune \\\) -exec bash -c \'echo \"\$0\"\' {} \\\;
name2
s=$(date +%s%N)
name2_num=$(name2 | wc -l)
e=$(date +%s%N)
name2_perf=$((e-s))
printf "  [# of files] $name2_num [Runtime(ns)] $name2_perf\n\n"

echo \> find \""$dir"\" -not -path \""$dir/Prune_me*"\" -exec bash -c \'echo \"\$0\"\' {} \\\;
name3
s=$(date +%s%N)
name3_num=$(name3 | wc -l)
e=$(date +%s%N)
name3_perf=$((e-s))
printf "  [# of files] $name3_num [Runtime(ns)] $name3_perf\n\n"

echo "Cleaning up test files..."
cleanup
185
BroSlow

Один из вариантов - исключить все результаты, содержащие имя каталога, с помощью grep. Например:

find . -name '*.js' | grep -v excludeddir
58
Joshua

Это единственный, который работал на меня.

find / -name NameOfFile ! -path '*/Directory/*'

Поиск "NameOfFile" исключая "Каталог". Сделай акцент на звезды *.

43
DimiDak

Я предпочитаю нотацию -not ... это более читабельно:

find . -name '*.js' -and -not -path directory
39
mpapis

Используйте опцию -Prune. Итак, что-то вроде:

find . -type d -name proc -Prune -o -name '*.js'

'-Type d -name proc -Prune' ищет только каталоги с именем proc, которые нужно исключить.
'-O' является оператором 'ИЛИ'.

18
Drew Frezell

Это формат, который я использовал для исключения некоторых путей:

$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"

Я использовал это, чтобы найти все файлы не в пути ". *":

$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
14
user1882879

-Prune определенно работает и является лучшим ответом, потому что он предотвращает спуск в каталог, который вы хотите исключить. -not -path, который по-прежнему ищет исключенный каталог, он просто не печатает результат, что может быть проблемой, если исключенный каталог является подключенным сетевым томом или у вас нет разрешений.

Сложность в том, что find очень точно относится к порядку аргументов, поэтому, если вы не получите их правильно, ваша команда может не сработать. Порядок аргументов обычно таков:

find {path} {options} {action}

{path}: сначала поместите все аргументы, связанные с путем, например . -path './dir1' -Prune -o

{options}: У меня больше всего успеха, когда -name, -iname, etc последний вариант в этой группе. Например. -type f -iname '*.js'

{action}: вы захотите добавить -print при использовании -Prune

Вот рабочий пример:

# setup test
mkdir dir1 dir2 dir3
touch dir1/file.txt; touch dir1/file.js
touch dir2/file.txt; touch dir2/file.js
touch dir3/file.txt; touch dir3/file.js

# search for *.js, exclude dir1
find . -path './dir1' -Prune -o -type f -iname '*.js' -print

# search for *.js, exclude dir1 and dir2
find . \( -path './dir1' -o -path './dir2' \) -Prune -o -type f -iname '*.js' -print
13
wisbucky

Подход -path -Prune также работает с подстановочными знаками в пути. Вот оператор find, который найдет каталоги для сервера git, обслуживающего несколько репозиториев git, оставляя внутренние каталоги git:

find . -type d \
   -not \( -path */objects -Prune \) \
   -not \( -path */branches -Prune \) \
   -not \( -path */refs -Prune \) \
   -not \( -path */logs -Prune \) \
   -not \( -path */.git -Prune \) \
   -not \( -path */info -Prune \) \
   -not \( -path */hooks -Prune \)  
9
Wolfgang Fahl

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

find . -path ./misc -Prune -o -name '*.txt' -print

find начнет поиск файлов и каталогов в текущем каталоге, отсюда find ..

Параметр -o обозначает логическое OR и ​​разделяет две части команды:

[ -path ./misc -Prune ] OR [ -name '*.txt' -print ]

Любой каталог или файл, который не каталог ./misc, не пройдет первый тест -path ./misc. Но они будут проверены против второго выражения. Если их имя соответствует шаблону *.txt, они печатаются из-за опции -print.

Когда find достигает каталога ./misc, этот каталог удовлетворяет только первому выражению. Таким образом, опция -Prune будет применена к нему. Он говорит команде поиска: не исследовать этот каталог. Таким образом, любой файл или каталог в ./misc даже не будет проверен командой find, не будет проверен на соответствие второй части выражения и не будет напечатан.

8
Istopopoki

Чтобы исключить несколько каталогов:

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" \)

Чтобы добавить каталоги, добавьте -o -path "./dirname/*":

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" -o -path "./dir3/*"\)

Но, возможно, вам следует использовать регулярное выражение , если нужно исключить много каталогов.

8
JBENOIT

Для рабочего решения (проверено на Ubuntu 12.04 (Precise Pangolin)) ...

find ! -path "dir1" -iname "*.mp3"

будет искать файлы MP3 в текущей папке и подпапках, за исключением подпапки dir1.

Использование:

find ! -path "dir1" ! -path "dir2" -iname "*.mp3"

... чтобы исключить dir1 И dir2

7
james dupin

Вы можете использовать опцию Prune для достижения этой цели. Как например:

find ./ -path ./beta/* -Prune -o -iname example.com -print

Или обратный вариант grep "grep -v":

find -iname example.com | grep -v beta

Вы можете найти подробные инструкции и примеры в команда Linux find исключает каталоги из поиска.

6
Siju V
find -name '*.js' -not -path './node_modules/*' -not -path './vendor/*'

кажется, работает так же, как

find -name '*.js' -not \( -path './node_modules/*' -o -path './vendor/*' \)

и легче запомнить ИМО.

4
Funkodebat

Для тех из вас, кто работает в более старых версиях UNIX, которые не могут использовать - путь или - нет

Протестировано на SunOS 5.10 bash 3.2 и SunOS 5.11 bash 4.4

find . -type f -name "*" -o -type d -name "*excluded_directory*" -Prune -type f
3
JaredTS486

Я использовал find, чтобы предоставить список файлов для xgettext, и хотел опустить конкретный каталог и его содержимое. Я перепробовал множество перестановок -path в сочетании с -Prune, но не смог полностью исключить каталог, который я хотел удалить.

Хотя я смог игнорировать содержимое каталога, который я хотел игнорировать, find затем вернул сам каталог как один из результатов, что привело к сбою xgettext в результате (не принимает каталоги; только файлы).

Мое решение состояло в том, чтобы просто использовать grep -v, чтобы пропустить каталог, который я не хотел в результатах:

find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext

Есть ли аргумент для find, который будет работать на 100%, я не могу сказать наверняка. Использование grep было быстрым и простым решением после некоторой головной боли.

3
Lemmings19
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -Prune
3
The Archetypal Paul

Для того, что мне было нужно, это работало так: находя landscape.jpg на всех серверах, начиная с root, и исключая поиск в каталоге /var:

find / -maxdepth 1 -type d | grep -v /var | xargs -I '{}' find '{}' -name landscape.jpg

find / -maxdepth 1 -type d перечисляет все d каталоги в /

grep -v /var исключает `/ var 'из списка

xargs -I '{}' find '{}' -name landscape.jpg выполнить любую команду, например find, с каждым каталогом/результатом из списка

2
adrianTNT

Это подходит для меня на Mac:

find . -name *.php -or -path "./vendor" -Prune -or -path "./app/cache" -Prune

Он исключит vendor и app/cache dir для имени поиска, к которому добавляется php.

2
jiahut

Ни один из предыдущих ответов не подходит для Ubuntu. Попробуй это:

find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"

Я нашел это здесь

2
sixro

how-to-use-Prune-option-of-find-in-sh - отличный ответ от Laurence Gonsalves о том, как работает -Prune.

И вот общее решение:

find /path/to/search                    \
  -type d                               \
    \( -path /path/to/search/exclude_me \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -Prune                              \
  -o                                    \
  -type f -name '*\.js' -print

Чтобы избежать многократного ввода /path/to/seach/, оберните find в пару pushd .. popd.

pushd /path/to/search;                  \
find .                                  \
  -type d                               \
    \( -path ./exclude_me               \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -Prune                              \
  -o                                    \
  -type f -name '*\.js' -print;         \
 popd
1
go2null

Лучше использовать действие exec, чем цикл for:

find . -path "./dirtoexclude" -Prune \
    -o -exec Java -jar config/yuicompressor-2.4.2.jar --type js '{}' -o '{}' \;

exec ... '{}' ... '{}' \; будет выполнен один раз для каждого соответствующего файла, заменив скобки '{}' текущим именем файла.

Обратите внимание, что фигурные скобки заключены в одинарные кавычки, чтобы защитить их от интерпретации как пунктуации сценария оболочки*,.


Заметки

* Из раздела ПРИМЕРЫ справочной страницы find (GNU findutils) 4.4.2

1
Alberto

Я попробовал команду выше, но ни один из тех, кто использует "-Prune", не работает для меня. В конце концов я попробовал это с командой ниже:

find . \( -name "*" \) -Prune -a ! -name "directory"
1
Jolly Liu

Я нашел имя функции в исходных файлах C исключая * .o и исключая * .swp и exclude (не обычный файл) и исключая вывод dir с помощью этой команды:

find .  \( ! -path "./output/*" \) -a \( -type f \) -a \( ! -name '*.o' \) -a \( ! -name '*.swp' \) | xargs grep -n soc_attach
1
Ivan Ivanovich

TLDR: понять ваши корневые каталоги и настроить поиск оттуда, используя опцию -path <excluded_path> -Prune -o. Не включайте конечный / в конец исключенного пути.

Пример:

find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print


Чтобы эффективно использовать find, я считаю, что необходимо хорошо понимать структуру каталогов вашей файловой системы. На моем домашнем компьютере установлены жесткие диски с несколькими ТБ, резервная копия которых хранится примерно для половины содержимого с использованием rsnapshot (т.е. rsync). Несмотря на то, что резервное копирование выполняется на физически независимый (дублирующий) диск, он монтируется в корневом каталоге моей системы (/): /mnt/Backups/rsnapshot_backups/:

/mnt/Backups/
└── rsnapshot_backups/
    ├── hourly.0/
    ├── hourly.1/
    ├── ...
    ├── daily.0/
    ├── daily.1/
    ├── ...
    ├── weekly.0/
    ├── weekly.1/
    ├── ...
    ├── monthly.0/
    ├── monthly.1/
    └── ...

Каталог /mnt/Backups/rsnapshot_backups/ в настоящее время занимает ~ 2,9 ТБ, с ~ 60M файлами и папками; простой просмотр этого содержимого требует времени:

## As Sudo (#), to avoid numerous "Permission denied" warnings:

# date; echo; \
  time find /mnt/Backups/rsnapshot_backups | wc -l; echo; \
  time du /mnt/Backups/rsnapshot_backups -d 0; echo; \
  time rsnapshot du    ## << more accurate re: rsnapshot footprint

Wed 22 May 2019 10:37:14 AM PDT

34:07.30    ## 34 min
60314138    ## 60.3M files, folders

3112240160  /mnt/Backups/rsnapshot_backups    ## 3.1 TB
33:51.88    ## 34 min

2.9T    /mnt/Backups/rsnapshot_backups/hourly.0/
4.1G    /mnt/Backups/rsnapshot_backups/hourly.1/
...
4.7G    /mnt/Backups/rsnapshot_backups/weekly.3/
2.9T    total    ## 2.9 TB, per Sudo rsnapshot du (more accurate)
2:34:54        ## 2 hr 35 min

Таким образом, в любое время, когда мне нужно найти файл в моем / (корневом) разделе, мне нужно иметь дело (избегать, если это возможно) с обходом моего раздела резервных копий.


ПРИМЕРЫ

Среди подходов, по-разному предложенных в этой теме ( Как исключить каталог из команды find. Command ), я считаю, что поиск с использованием принятого ответа очень много быстрее - с оговорками.

Решение 1

Допустим, я хочу найти системный файл libname-server-2.a, но я не хочу искать в моих резервных копиях rsnapshot. Чтобы быстро найти системный файл, используйте путь исключения /mnt - not /mnt/ или /mnt/Backups, ...):

## As Sudo (#), to avoid numerous "Permission denied" warnings:

# time find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
real    0m8.644s              ## 8.6 sec  <<< NOTE!
user    0m1.669s
 sys    0m2.466s

## As regular user (victoria), with alternate timing mechanism,
## as using 2?/dev/null to suppress "Permission denied" warnings:

$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt -Prune -o \
    -name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
    TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 3 sec     ## ~3 sec  <<< NOTE!

... находит этот файл всего за несколько секунд, в то время как это занимает намного дольше (появляется пройти через все "исключенные" каталоги):

## As Sudo (#), to avoid numerous "Permission denied" warnings:

# time find / -path /mnt/ -Prune -o -name "*libname-server-2.a*" -print
find: warning: -path /mnt/ will not match anything because it ends with /.
/usr/lib/libname-server-2.a
real    33m10.658s            ## 33 min 11 sec (~231-663x slower!)
user    1m43.142s
 sys    2m22.666s

## As regular user (victoria), with alternate timing mechanism,
## as using 2?/dev/null to suppress "Permission denied" warnings:

$ START="$(date +"%s")" && find 2>/dev/null / -path /mnt/ -Prune -o \
    -name "*libname-server-2.a*" -print; END="$(date +"%s")"; \
    TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/usr/lib/libname-server-2.a
find command took 1775 sec    ## 29.6 min

Решение 2

Другое решение, предлагаемое в этой теме ( SO # 4210042 ), также работает плохо:

## As Sudo (#), to avoid numerous "Permission denied" warnings:

# time find / -name "*libname-server-2.a*" -not -path "/mnt"
/usr/lib/libname-server-2.a
real    33m37.911s            ## 33 min 38 sec (~235x slower)
user    1m45.134s
 sys    2m31.846s

# time find / -name "*libname-server-2.a*" -not -path "/mnt/*"
/usr/lib/libname-server-2.a
real    33m11.208s            ## 33 min 11 sec
user    1m22.185s
 sys    2m29.962s

Резюме

В "Решении 1" (... -path <excluded_path> -Prune -o ...) кажется, что всякий раз, когда вы добавляете конечный /, команда затем рекурсивно вводит (все эти) каталоги /mnt/* - что в моем случае из-за подкаталогов /mnt/Backups/rsnapshot_backups/* дополнительно включает в себя ~ 2.9 TB файлов для поиска! Не добавляя завершающий /, поиск должен завершиться практически сразу (в течение нескольких секунд).

"Решение 2" (... -not -path <exclude path> ...) также, по-видимому, рекурсивно ищет в исключенных каталогах, не возвращая эти попадания, но излишне тратя это время поиска.


Поиск в этих резервных копиях rsnapshot:

Чтобы найти файл в одной из моих ежечасных/ежедневных/еженедельных/ежемесячных резервных копий rsnapshot):

$ START="$(date +"%s")" && find 2>/dev/null /mnt/Backups/rsnapshot_backups/daily.0 -name '*04t8ugijrlkj.jpg'; END="$(date +"%s")"; TIME="$((END - START))"; printf 'find command took %s sec\n' "$TIME"
/mnt/Backups/rsnapshot_backups/daily.0/snapshot_root/mnt/Vancouver/temp/04t8ugijrlkj.jpg
find command took 312 sec   ## 5.2 minutes: despite apparent rsnapshot size
                            ## (~4 GB), it is in fact searching through ~2.9 TB)

Исключая вложенный каталог:

Здесь я хочу исключить вложенный каталог, например, /mnt/Vancouver/projects/ie/claws/data/* при поиске из /mnt/Vancouver/projects/:

$ time find . -iname '*test_file*'
./ie/claws/data/test_file
./ie/claws/test_file
0:01.97

$ time find . -path '*/data' -Prune -o -iname '*test_file*' -print
./ie/claws/test_file
0:00.07

В сторону: Добавление -print в конце команды подавляет распечатку исключенного каталога:

$ find / -path /mnt -Prune -o -name "*libname-server-2.a*"
/mnt
/usr/lib/libname-server-2.a

$ find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
1
Victoria Stuart

Не уверен, что это будет охватывать все случаи Edge, но следующее было бы довольно просто и легко попробовать:

ls -1|grep -v -e ddl -e docs| xargs rm -rf

Это должно удалить все файлы/каталоги из текущего каталога, кроме "ddls" и "docs".

0
Arnab

Если каталоги поиска имеют шаблон (в моем случае большую часть времени); Вы можете просто сделать это, как показано ниже:

find ./n* -name "*.tcl" 

В приведенном выше примере; он ищет во всех подкаталогах, начинающихся с "n".

0
Prince Bhanwra

Для FreeBSD пользователей:

 find . -name '*.js' -not -path '*exclude/this/dir*'
0
Richard Bartisek

Это работает, потому что findTESTS файлы для pattern " * foo * ":

find ! -path "dir1" ! -path "dir2" -name "*foo*"

но он работает НЕ, если вы не используете pattern (find не TEST файл). Таким образом, find не использует ранее оцененное " true " & " false "bools. Пример для не работающего варианта использования с вышеприведенными обозначениями:

find ! -path "dir1" ! -path "dir2" -type f

Нет find ТЕСТИРОВАНИЯ! Поэтому, если вам нужно найти файлы без сопоставления с образцом, используйте -Prune. Кроме того, благодаря использованию Prune find всегда быстрее, в то время как он действительно пропускает те каталоги, а не сопоставляет их или, лучше, не сопоставляет их. Так что в этом случае используйте что-то вроде:

find dir -not \( -path "dir1" -Prune \) -not \( -path "dir2" -Prune \) -type f

или же:

find dir -not \( -path "dir1" -o -path "dir2" -Prune \) -type f

С уважением

0
d0n

Я нашел предложения на этой странице, и многие другие страницы просто не работают в моей системе Mac OS X. Тем не менее, я нашел вариант, который работает для меня.

Основная идея состоит в том, чтобы искать Macintosh HD, но избегать обхода всех внешних томов, которые в основном состоят из резервных копий Time Machine, резервных копий изображений, подключенных общих ресурсов и архивов, но без необходимости размонтировать их все, что зачастую нецелесообразно.

Вот мой рабочий скрипт, который я назвал "findit".

#!/usr/bin/env bash
# inspired by http://stackoverflow.com/questions/4210042/exclude-directory-from-find-command Danile C. Sobral
# using special syntax to avoid traversing. 
# However, logic is refactored because the Sobral version still traverses 
# everything on my system

echo ============================
echo find - from cwd, omitting external volumes
date
echo Enter Sudo password if requested
Sudo find . -not \( \
-path ./Volumes/Archive -Prune -o \
-path ./Volumes/Boot\ OS\ X -Prune -o \
-path ./Volumes/C \
-path ./Volumes/Data -Prune -o \
-path ./Volumes/jas -Prune -o \
-path ./Volumes/Recovery\ HD -Prune -o \
-path ./Volumes/Time\ Machine\ Backups -Prune -o \
-path ./Volumes/SuperDuper\ Image -Prune -o \
-path ./Volumes/userland -Prune \
\) -name "$1" -print
date
echo ============================
iMac2:~ jas$

Различные пути связаны с внешними томами архивов, Time Machine, виртуальными машинами, другими подключенными серверами и так далее. В некоторых именах томов есть пробелы.

Хороший тестовый запуск - "findit index.php", потому что этот файл встречается во многих местах моей системы. С этим сценарием поиск по основному жесткому диску занимает около 10 минут. Без этих исключений, это занимает много часов.

0
Jeffrey Simon