it-swarm.com.ru

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

Я хочу найти файлы, которые заканчиваются на _peaks.bed, но исключают файлы в папках tmp и scripts.

Моя команда такая:

 find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)

Но это не сработало. Файлы в папках tmp и script по-прежнему будут отображаться.

У кого-нибудь есть идеи по этому поводу?

77
Hanfei Sun

Вот как вы можете указать это с помощью find:

find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"

Объяснение:

  • find . - начать поиск из текущего рабочего каталога (рекурсивно по умолчанию)
  • -type f - укажите find, что вам нужны только файлы в результатах
  • -name "*_peaks.bed" - поиск файлов с именем, заканчивающимся на _peaks.bed
  • ! -path "./tmp/*" - исключить все результаты, путь которых начинается с ./tmp/
  • ! -path "./scripts/*" - также исключить все результаты, путь которых начинается с ./scripts/

Тестирование решения:

$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"

./d/4
./c/3
./e/a
./e/b
./e/5

Вы были довольно близки, опция -name учитывает только базовое имя, а -path рассматривает весь путь =)

173
sampson-chen

Вот один из способов сделать это ...

find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
8
alex

Попробуйте что-то вроде

find . \( -type f -name \*_peaks.bed -print \) -or \( -type d -and \( -name tmp -or -name scripts \) -and -Prune \)

и не удивляйтесь, если я немного ошибаюсь. Если целью является exec (вместо print), просто замените его на месте.

0
DrC

для меня это решение не сработало в команде exec с find, не знаю почему, поэтому мое решение

find . -type f -path "./a/*" -Prune -o -path "./b/*" -Prune -o -exec gzip -f -v {} \;

Объяснение: То же самое, что и Сампсон-чен с добавлением

-Пруна - игнорировать исходящий путь ...

-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
0
Al3x

Вы можете попробовать ниже:

find ./ ! \( -path ./tmp -Prune \) ! \( -path ./scripts -Prune \) -type f -name '*_peaks.bed'
0
Jacky Jiang