Использование `find` для нескольких расширений файлов

16

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

find . -name '*.java' | xargs wc -l

Как я могу изменить findпараметры команды, чтобы они соответствовали более чем одному расширению файла? Например, я хотел бы использовать вышеуказанную операцию для файлов CPP, C и H.

Ксавье
источник
Этот вопрос на самом деле о findкоманде, так как именно здесь вы ищете соответствующие файлы.
iglvzx
1
Кроме того , использовать либо find -print0 | xargs -0конструкцию или даже лучше и проще: find . -name '*.cpp' -o -name '*.c' -o -name '*.h' -exec wc -l {} +. Это позволит избежать проблем с именами файлов (пробелы, новые строки и т. Д.) И (очень) хорошо настраивается.
Даниэль Андерссон

Ответы:

16

Используйте -oопцию для ИЛИ. Например, этот список будет .cpp, .cи .hфайлы:

find . -name \*.cpp -o -name \*.c -o -name \*.h
JOTN
источник
Ах. Больше *не нужно экранировать, если отформатирован как код. Полностью пропустил это. :)
iglvzx
Да, потребовалось три редактирования двумя людьми, но мы получили это.
JOTN
2
Это не сработало для меня в OSX (соответствует только последнему имени * .ext) - мне пришлось использовать круглые скобки, как предложено @smokinguns ниже.
Галаад
2

Вам нужно будет использовать опцию -o. Например, инструкция ниже находит все файлы png, jpg и gif в папке.

find . \( -iname \*.png -o -iname \*.jpg -o -iname \*.gif \)

Я использую опцию -iname, чтобы совпадение не чувствительно к регистру.

smokinguns
источник
1
iname доступен не во всех версиях find.
JOTN
2
$ find /path/ -name '*.cpp' -or -name '*.c' -or -name '*.h'

«-Или» говорит, что я ищу один или оба из двух подходов.

Недавно я написал краткое руководство по использованию find с логическими операторами здесь: http://jamesfishwick.com/2012/linux-find-and-boolean-operators

two7s_clash
источник
1

Хотя все ответы более или менее одинаковы, я не считаю их читаемыми с несколькими именами и булевыми операторами между ними.

Я думаю, что это может быть более элегантным решением:

$ find . -type f | grep -E "\.java$|\.cpp$|\.c$"

Давайте разберемся с этим

  • find . рекурсивно находит все файлы в текущем пути (при необходимости измените путь на другой)
  • -type fсужает поиск только по файлам (не слишком большой прирост скорости, но все же ...)
  • | grep -EЯ использовал это, чтобы получить grep распознавать или ( |) оператор в Mac OS X, которая использует FreeBSD grep , GNU grep в этом не нуждается (проверьте в вашем manфайле).
  • "\.java$|\.cpp$|\.c$"регулярное выражение , которое включает в себя файлы, имена которых оканчиваются с .java, .cppи .c(добавить в них вам нужно)

Затем вы можете передать полученный список для дальнейшей обработки, например,

$ find . -type f | grep -E "\.java$|\.cpp$|\.c$" | xargs sed -i '' $'/s/\r$//'

В этом примере удаляется CRLFокончание строки DOS / Windows для OS X / Linux LF(это также sedсинтаксис OS X , проверьте специфику вашей версии).

MacMladen
источник
Я хотел найти все типы видеофайлов, используя 25 различных параметров соответствия расширений. Это был единственный подход, который работал для меня. (Ubuntu 14.04 LTS)
Старейшина Гик
0

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

find path/to/dir -name "*.ext1" -o -name "*.ext2"

объяснение

  1. Первый параметр - это каталог, который вы хотите найти.
  2. По умолчанию findрекурсия.
  3. -oОзначает -or. Таким образом, выше означает поиск этого символа или этого. Если у вас есть только один шаблон, то нет необходимости -o.
  4. Кавычки вокруг шаблона подстановки обязательны.
Шиталь шах
источник