Знайдіть файли у кількох назвах папок


44

Я намагаюся список всіх файлів з dir1, dir2, dir3і dir4які можуть перебувати в будь-якому місці в підкаталозі моїх cwdвикористовуючи findкоманду. Я спробував наступне без успіху:

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

Я також спробував posix-extended. Як я можу перерахувати ці файли?


знайти. -тип f -regextype sed -regex ". * / dir [1-4] / [a-z0-9] *" .. найкоротша відповідь поки що :) див. відповідь нижче .. unix.stackexchange.com/a/390333 / 242983
alpha_989

Відповіді:


59

І якщо ви хочете знайти три папки з ім'ям 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

Краще скористатися директивою -ath:

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

Що означає: знайдіть усі файли в поточному каталозі, де на шляху є 'dir1' або 'dir2' або 'dir3' або 'dir4'.


Ви поставили дужки в неправильному місці. Дивіться також -aі -oдля стандартного еквівалента ГНУ -and/ -or.
Стефан Шазелас

4

Просто щоб повідомити всім. Додавання .*/перед кожним dirвирішеним завданням, оскільки regexце збігається з повним шляхом, як здається.


3

Це моя перша ідея, прочитавши попередні відповіді:

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

При цьому враховується, що регулярний вираз повинен відповідати всьому імені файлу, і це легше зрозуміти.


2

Зразок швидкого (!) Пошуку конкретних файлів (access_log) у декількох місцях, визначених wildcard (домашній каталог) та загальним каталогом журналів 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, на мою думку, я відчуваю себе більш універсальним, ніж find -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.