Найти файлы в нескольких именах папок


43

Я пытаюсь перечислить все файлы из dir1, dir2, dir3и dir4которые могут быть в любом месте , как подкаталог моих с cwdпомощью findкоманды. Я попробовал следующее безуспешно:

find . -type f -regextype posix-egrep -regex 'dir1/.+|dir2/.+|dir3/.+|dir4/.+'

Я тоже старался posix-extended. Как я могу перечислить эти файлы?


находить . -type f -regextype sed -regex ". * / dir [1-4] / [a-z0-9] *" .. самый короткий ответ до сих пор :) см. ответ ниже .. unix.stackexchange.com/a/390333 / 242983
alpha_989,

Ответы:


58

И если вы хотите найти три папки с именем foo, barи bazдля всех *.pyфайлов, используйте следующую команду:

find foo bar baz -name "*.py"

так что если вы хотите отобразить файлы из dir1 dir2 dir3использованияfind dir1 dir2 dir3 -type f

попробуй это find . \( -name "dir1" -o -name "dir2" \) -exec ls '{}' \;


Я должен был уточнить. Возможно, у меня нет пути к файлам, которые я хочу найти. Я только знаю, что они являются подкаталогами текущего каталога.
Аарон

используйте ./dirвместоdir
harish.venkat

Директория все еще должна быть в cwd, хотя она может быть на два уровня ниже (например ./path/to/dir1), в этом случае ./dir1ее не будет.
Аарон

отредактировал ответ.
harish.venkat

8

Лучше всего использовать директиву -path:

find .  \( -type f -and -path '*/dir1/*' -or -path '*/dir2/*' -or -path '*/dir3/*' -or -path '*/dir4/*' \)

Что означает: найти все файлы в текущем каталоге, где в пути есть «dir1», «dir2», «dir3» или «dir4».


У вас есть скобки не в том месте. Смотрите также -aи -oстандартный эквивалент GNU -and/ -or.
Стефан

4

Просто чтобы все знали. Добавление .*/перед каждым dirрешило проблему, так regexкак, кажется, сопоставление с полным путем.


3

Это моя первая идея после прочтения предыдущих ответов:

find . -type f -regextype posix-egrep -regex ".*/(dir1|dir2|dir3|dir4)/.+"

Это принимает во внимание, что регулярное выражение должно соответствовать всему имени файла, и это легче понять.


2

Пример быстрого (!) Поиска определенных файлов (access_log) в нескольких местах, определенных подстановочными знаками (домашний каталог) и общим каталогом журналов apache2, с применением также фильтрации имен для исключения журналов ssl и старых архивов gzipped. Непосредственно не отвечает на вопрос здесь, но может быть полезным для кого-то, кто нашел эти инструкции (как я).

find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*"

Будьте осторожны с пробелами, особенно рядом с \(и \).

Кстати, я использовал его для apachetop, чтобы найти наиболее активные веб-сайты на моем сервере.

apachetop -d1 -s9 -p $(find / \( -path "*var/log/apache2*" -o -path "*home/*/logs*" \) -type f  -name "*access_log" ! -name "*ssl*" -print | sed 's/^/-f '/)

2

вам не нужно указывать от dir1 до dir4 по имени, если вы используете regextype

find . -type f -regextype sed -regex ".*/dir[1-4]/[^/]*"
  • type f: найти файлы, а не каталоги
  • regextype sed: использует sed regextype
  • regex: поиск с использованием регулярных выражений по всему пути
  • ".*/dir[1-4]/[a-z0-9]*":. * в начале означает любое количество символов, которые могут иметь тип (char / number / backslash (/) и т. д.); dir [1-4] означает поиск «dir», за которым следует число от 1 до 4; / [^ /] * утверждает, что после dir1-4 пропускаются любые пути, в которых есть /, поэтому он возвращает только файлы в каталоге dir1-dir4 и игнорирует все подкаталоги, которые могут находиться в dir1-dir4.

создал каталог для тестирования: https://github.com/alphaCTzo7G/stackexchange/tree/master/linux/findSolution04092017


(1) Возможно, мы никогда не узнаем точную ситуацию или требования Аарона, но другие ответы сделали разумное решение, что у него есть четыре справочника, имена которых не указаны. (Они могут быть red, green, blueи yellow, или же они могут быть John, Paul, Georgeи Ringo.) Ваш ответ предполагает , что они в буквальном смысле dir1 , dir2, dir3и dir4. … (Продолжение)
Скотт

(Продолжение)… (2) Почему вы предполагаете, что Аарон не хочет искать в подкаталогах? Кажется, он говорит, что делает. (3) Почему вы ограничивая поиск в файлах, имена которых содержат только строчные буквы и цифры ( за исключением вещей , как foo_bar, foo.txtи FOO)? (4) Почему ваш текст объясняет, /[^/]*когда ваш ответ не использует его?
Скотт,

Привет Скотт, вот за твой комментарий.
alpha_989

(1-3). он упоминает «Я пытаюсь перечислить все файлы из dir1, dir2, dir3 и dir4 », которые могут быть где угодно в качестве подкаталога моего cwd , что означает, что dir1-dir4 может быть где угодно, но он хочет найти файл правильно в пределах dir1-dir4. Конечно, если это не dir1-dir4, вы должны изменить его на конкретные имена, используя красный \ | синий \ | зеленый \ | и т.д ..
alpha_989

4. опечатка там .. Я использовал [a-z0-9] * до того ... потом понял, что [^ /] * короче и более инклюзивно .. забыл изменить его, когда я это опубликовал. Спасибо за ваши осторожные комментарии.
alpha_989,

0

Я знаю, что вы указали, что используя find, но только для показа других опций, которые можно использовать, вы можете использовать xargs:

find . -type d | grep -E "dir1$|dir2$" | xargs ls  

find . -name "dir1" -or -name "dir2" | xargs ls

Вы можете иметь файл с именем «папки», который содержит что-то вроде:

$ cat folders
dir1
dir2
dir3
dir4

Затем вы можете сделать что-то вроде этого:

$ cat folders | xargs -I % find . -type d -name % | xargs ls
./Documents/dir1:
file1  file2  file3  file4

./Documents/dir2:
file1  file2  file3  file4

./Documents/dir3:
file1  file2  file3  file4

./Documents/dir4:
file1  file2  file3  file4

xargs по моему мнению, я чувствую себя более универсальным, чем найти -exec. Также вы можете сделать некоторые сумасшедшие вещи, такие как

$ cat << EOF | xargs -I {} find ~ -name "{}" | xargs ls
> dir1
> dir2
> dir3
> EOF
/home/user/Documents/dir1:
file1  file2  file3  file4

/home/user/Documents/dir2:
file1  file2  file3  file4

/home/user/Documents/dir3:
file1  file2  file3  file4
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.