Я хочу , чтобы найти файлы , которые заканчиваются _peaks.bed
, но исключить файлы в tmp
и scripts
папках.
Моя команда такая:
find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)
Но это не сработало. Файлы в tmp
и по- script
прежнему будет отображаться папки.
Есть у кого-нибудь идеи по этому поводу?
_peaks.bed
.find
, но поскольку вопрос помечен как Linux, это не проблема. Хороший ответ..
в исходном запросе поиска, вы должны использовать его для каждого исключаемого пути. Соответствие пути довольно строгое, оно не выполняет нечеткого поиска. Так что если вы воспользуетесь им,find / -type f -name *.bed" ! -path "./tmp/"
это не сработает. вам нужно! -path "/tmp"
сделать его счастливым.$ ! -path "./directory/*"
-prune
а не проверяйте каждый файл в дереве». Если ваши исключенные каталоги занимают очень много места или содержат множество файлов, и вы заботитесь о производительности, используйте эту-prune
опцию.Вот один из способов сделать это ...
find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
источник
find
, а не только с GNUfind
. Однако вопрос помечен как Linux, так что это не критично.Использовать
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
или
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
или
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
Порядок важен. Он оценивается слева направо. Всегда начинайте с исключения пути.
Объяснение
Не используйте
-not
(или!
) для исключения всего каталога. Используйте-prune
. Как объяснено в руководстве:и в руководстве по поиску GNU:
Действительно, если вы используете
-not -path "./pathname"
, find будет оценивать выражение для каждого узла ниже"./pathname"
.Выражения find - это просто оценка условий.
\( \)
- групповая работа (можно использовать-path "./tmp" -prune -o -path "./scripts" -prune -o
, но более многословно).-path "./script" -prune
- если-path
возвращает истину и является каталогом, вернуть истину для этого каталога и не спускаться в него.-path "./script" ! -prune
- оценивается как(-path "./script") AND (! -prune)
. Он меняет «всегда верно» для слова «всегда ложно». Это позволяет избежать печати"./script"
совпадений.-path "./script" -prune -false
- поскольку-prune
всегда возвращает истину, вы можете следовать за ним,-false
чтобы сделать то же самое, чем!
.-o
- Оператор ИЛИ. Если между двумя выражениями не указан оператор, по умолчанию используется оператор AND.Следовательно,
\( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
расширяется до:[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
Печать здесь важна, потому что без нее расширяется до:
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
добавляется с помощью find - поэтому в большинстве случаев вам не нужно добавлять его в выражение. А поскольку-prune
вернет true, он напечатает «./script» и «./tmp».В других это не обязательно, потому что мы переключились
-prune
на всегда возвращать false.Подсказка: вы можете использовать,
find -D opt expr 2>&1 1>/dev/null
чтобы увидеть, как он оптимизирован и расширен,find -D search expr 2>&1 1>/dev/null
чтобы увидеть, какой путь отмечен.источник
Попробуйте что-нибудь вроде
find . \( -type f -name \*_peaks.bed -print \) -or \( -type d -and \( -name tmp -or -name scripts \) -and -prune \)
и не удивляйтесь, если я ошибаюсь. Если целью является выполнение (вместо печати), просто замените его на место.
источник
для меня это решение не сработало с командой exec с find, действительно не знаю почему, поэтому мое решение
find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
Пояснение: то же, что и сампсон-чен, с добавлением
-prune - игнорировать исходящий путь ...
-o - Затем, если совпадений нет, распечатать результаты (обрезать каталоги и распечатать оставшиеся результаты)
18:12 $ mkdir a b c d e 18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b 18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \; gzip: . is a directory -- ignored gzip: ./a is a directory -- ignored gzip: ./b is a directory -- ignored gzip: ./c is a directory -- ignored ./c/3: 0.0% -- replaced with ./c/3.gz gzip: ./d is a directory -- ignored ./d/4: 0.0% -- replaced with ./d/4.gz gzip: ./e is a directory -- ignored ./e/5: 0.0% -- replaced with ./e/5.gz ./e/a: 0.0% -- replaced with ./e/a.gz ./e/b: 0.0% -- replaced with ./e/b.gz
источник
find . -path ./scripts -prune -name '*_peaks.bed' -type f
. Не знаете, как исключить несколько каталогов. Здесь также отображается исключенный каталог верхнего уровня, даже еслиtype
он указан. Исключение с помощью Grep кажется более простым, если вы не хотите использовать prune для ускорения операции поиска.Вы можете попробовать следующее:
find ./ ! \( -path ./tmp -prune \) ! \( -path ./scripts -prune \) -type f -name '*_peaks.bed'
источник