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

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

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

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

Ответ 1

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

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), ANDed с type -d.

Дальнейшее действие - -o print, просто печать.

Ответ 2

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

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

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

Ответ 3

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

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 /full/path/exclude/this -prune \)..., Смотрите примечание [1], если вы хотите лучшего понимания.

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

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

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


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

Ответ 4

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

Мнение GNU

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

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

Рассуждение

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

Проблемы с -prune

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

  • find печатает обрезку каталога.

    • ИСТИНА. Это предполагаемое поведение, оно просто не спускается в него. Чтобы вообще не печатать каталог, используйте синтаксис, который логически опускает его.
  • -prune работает только с -print и никакими другими действиями.

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

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

Я установил простой тест трех верхних upvoted ответов по этому вопросу (заменил -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 и синтаксис Daniel C. Sobral заняли в среднем 10-25 мс. Синтаксис GetFree, который не использует -prune, занимает 865 мс. Итак, да, это довольно экстремальный пример, но если вы заботитесь о времени выполнения и делаете что-либо отдаленно интенсивным, вы должны использовать -prune.

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

Тест Script

#!/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

Ответ 5

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

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

Ответ 6

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

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

Поиск "MyFile", исключая "Directory". Сделай акцент на звезды *.

Ответ 7

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

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

Ответ 8

Используйте параметр -prune. Итак, что-то вроде:

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

'-type d -name proc -prune' ищет только каталоги с именем proc для исключения.
"-o" является оператором "OR".

Ответ 9

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

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

Я использовал это, чтобы найти все файлы, не содержащиеся в дорожках ". *":

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

Ответ 10

-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

Ответ 11

Подход "-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 \)  

Ответ 12

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

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

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

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

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

Ответ 13

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

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

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

Опция -o обозначает логическое ИЛИ и разделяет две части команды:

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

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

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

Ответ 14

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

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

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

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

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

... для исключения dir1 AND dir2

Ответ 15

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

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

Или инверсная опция grep grep -v:

find -iname example.com | grep -v beta

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

Ответ 16

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

похоже, работает так же, как

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

и легче запомнить IMO.

Ответ 17

find . -name '*.js' -\! -name 'glob-for-excluded-dir' -prune

Ответ 18

Я использовал 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 было быстрым и легким решением после некоторой головной боли.

Ответ 19

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

Протестировано на 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

Ответ 20

TL;DR: понять ваши корневые каталоги и настроить поиск оттуда, используя -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:

time find /mnt/Backups/rsnapshot_backups | wc -l
60314138    ## 60.3M files, folders
34:07.30    ## 34 min

time du /mnt/Backups/rsnapshot_backups -d 0
3112240160  /mnt/Backups/rsnapshot_backups    ## 3.1 TB
33:51.88    ## 34 min

time rsnapshot du    ## << more accurate re: rsnapshot footprint
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.), Я обнаружил, что поиск с использованием принятого ответа выполняется намного быстрее - с оговорками.

Решение 1

Допустим, я хочу найти системный файл libname-server-2.a, но не хочу искать в своих резервных копиях rsnapshot. Чтобы быстро найти системный файл, используйте путь исключения /mnt (т. /mnt Используйте /mnt, а не /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); I also use an alternate timing mechanism, as
## here I am 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); I also use an alternate timing mechanism, as
## here I am 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 "

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

т.е.

... -path <excluded_path> -prune -o ...

отмечая, что всякий раз, когда вы добавляете конечный / к исключенному пути, команда find затем рекурсивно вводит (все эти) каталоги /mnt/* - что в моем случае из-за подкаталогов /mnt/Backups/rsnapshot_backups/* дополнительно включает в себя ~ 2,9 ТБ файлов для поиска! Не добавляя трейлинг / поиск должен завершиться почти сразу (в течение нескольких секунд).

"Решение 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 : Добавление -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

Ответ 21

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

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

Я нашел здесь здесь

Ответ 22

как использовать-prune-option-of-find-in-sh является отличным ответом Laurence Гонсальвы о том, как работает -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

Ответ 23

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

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

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

Ответ 24

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

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

find / -maxdepth 1 -type d перечислены все д irectories в /

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

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

Ответ 25

Хороший способ избежать распечатки сокращенных каталогов - использовать -print (работает и для -exec) после правой стороны -or после -prune. Например,...

find . -path "*/.*" -prune -or -iname "*.j2"

напечатает путь ко всем файлам под текущим каталогом с расширением .j2 ", пропуская все скрытые каталоги. Опрятно. Но он также напечатает на распечатке полный путь каждого каталога, который пропускается, как отмечено выше. Тем не менее, следующее не...

find . -path "*/.*" -prune -or -iname "*.j2" -print

потому что логически существует скрытый -and после оператора -iname и до -print. Это связывает его с правой частью предложения -or из-за логического порядка операций и ассоциативности. Но в документах есть скрытый -print, если он (или любой из его двоюродных братьев... -print0 и т.д.) Не указан. Так почему же не левая часть печати -or? Очевидно (и я не понял этого из моего первого прочтения страницы руководства), это правда, если там нет -print -or -exec НИГДЕ, и в этом случае -print логически разбросано вокруг так, что все печатается. Если даже ОДНА операция print -style выражена в каком-либо предложении, все эти скрытые логические операции исчезнут, и вы получите только то, что вы укажете. Откровенно говоря, я мог бы предпочесть это с другой стороны, но тогда find с только описательными операторами, очевидно, ничего бы не сделал, так что я думаю, что это имеет смысл как есть. Как упомянуто выше, все это работает и с -exec, поэтому следующее дает полный ls -la листинг для каждого файла с желаемым расширением, но не перечисляет первый уровень каждого скрытого каталога,...

find . -path "*/.*" -prune -or -iname "*.j2" -exec ls -la -- {} +

Для меня (и других в этой теме) синтаксис find становится довольно барочным довольно быстро, поэтому я всегда добавляю парены, чтобы УВЕРЕН, что я знаю, что с чем связано, поэтому я обычно создаю макрос для типа-способности и сформировать все такие заявления как...

find . \( \( ... description of stuff to avoid ... \) -prune \) -or \
\( ... description of stuff I want to find ... [ -exec or -print] \)

Трудно ошибиться, настроив мир на две части. Я надеюсь, что это поможет, хотя вряд ли кто-то зачитает 30-й ответ и проголосует за него, но можно надеяться. :-)

Ответ 26

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

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

Ответ 27

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

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

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

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


Примечания

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

Ответ 28

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

find . \( -name "*" \) -prune -a ! -name "directory"

Ответ 29

Это работает, потому что find TESTS файлы для шаблона "* foo *":

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

но он работает НЕ, если вы не используете шаблон (findне TEST). Таким образом, find не использует свои прежние оцененные "истинные" и "ложные" 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

Привет

Ответ 30

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

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