действие поиска не работает для определенного поиска

действие поиска не работает для определенного поиска

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

find POD -type f -name *.mp3 -or -name *.ogg -ls

Который не производит никакого вывода. В то время как:

find POD -type f -name *.mp3 -or -name *.ogg

производит вывод, я также пробовал действия:

-printf "%p %k KB\n"
-exec ls -ls '{}' \;
-print0

но все это не дает никакого результата. Когда я использую любое из этих действий с другим выражением, например:

find . -maxdepth 1 -type f -printf "%p %k KB\n"

Я также получаю ожидаемый вывод. Кто-нибудь знает, в чем проблема? Я запускаю:

Linux irimi 3.10.37-1-MANJARO #1 SMP Mon Apr 14 20:56:29 UTC 2014 x86_64 GNU/Linux

aka современный дистрибутив Manjaro linux. Оболочка, которую я использую: /bin/bashверсия 4.3.8(1)-release.

Содержимое моей SHELLOPTSпеременной среды:

braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor

Моя BASHOPTSпеременная окружения:

cdspell:checkwinsize:cmdhist:complete_fullquote:dotglob:expand_aliases:extglob:extquote:force_fignore:histappend:hostcomplete:interactive_comments:nocaseglob:progcomp:promptvars:sourcepath

Опять же, любая помощь в попытке отладки будет очень признательна.

решение1

Есть ловушка си/илиключевые слова на find. orприменяются ко всем следующим параметрам, включая действие ( -lsв вашем примере). andвыражения без or(или присоединенные к and) оцениваются в порядке чтения с конечной остановкой как ложь. Нет implicit ().

Итак, команда find POD -type f -name *.mp3 -or -name *.ogg -lsозначает:

  • поиск (начиная с каталога POD) файлов --- если файл не найден: ОСТАНОВИТЬ
  • в противном случае (файл найден) проверка соответствия шаблону *.mp3 --- если соответствие шаблону: СТОП! (потому что ORприменяется отсюда и только в случае, если предыдущая команда не удалась (но только предыдущая команда, а не предыдущие группы команд)

и поскольку вы добавляете оператор выполнения ( -ls, -exec, -print....) в командную строку, то неявной команды нет -print, и поэтому нечего выполнять, если 1) все условия 1) истинны (файл и шаблон совпадают). Если вы удалите последний, то в конце каждого условия -lsбудет неявно распределено.-print

  • в противном случае, если шаблон не совпал, выполняется поиск всего, что соответствует шаблону (файл/каталог), *.oggи вывод их списка ( -lsкоманда не является условной, она выполняется только в том случае, если предыдущая команда/тест «шаблон» *.oggверна). Но из-за 1), 2) оценивается только для НЕ mp3-файлов. Если у вас нет .oggфайлов, вы ничего не увидите.

Решение 1 повторить команду выполнения в каждой логической ветви

   find POD -type f -name "*.mp3" -ls -or -name "*.ogg" -ls

Решение 2добавить (защищенную оболочкой) скобку

   find POD -type f \( -name "*.mp3" -ls -or -name "*.ogg" \) -ls

Примечание вам следует защитить шаблоны, чтобы избежать оценки шаблонов оболочки в текущем каталоге.

решение2

Я думаю, это из-за порядка оценки (отсутствия явного приоритета), например, если

-name '*.mp3' -o -name '*.ogg' -ls

тогда если -name '*.ogg'оценивается как ложь, lsдействие не выполняется. Вы можете получить ожидаемое поведение, сгруппировав выражения OR с помощью скобок - например, если

$ ls tests
file1.mp3  file2.mp3  file3.mp3

Затем

$ find tests \( -name '*.mp3' -o -name '*.ogg' \) -print
tests/file3.mp3
tests/file1.mp3
tests/file2.mp3

тогда как

$ find tests -name '*.mp3' -o -name '*.ogg' -print

не производит никакого вывода. Обратите внимание, что

$ find tests -name '*.mp3' -o -name '*.ogg'

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

$ find tests \( -name '*.mp3' -o -name '*.ogg' \) -print

Также обратите внимание, что хорошей практикой является заключение в кавычки или экранирование подстановок оболочки в findкоманде, чтобы оболочка не могла их раскрыть — см. раздел NON-BUGSна странице руководства find.

Связанный контент