encontrar ação que não funciona para pesquisa específica

encontrar ação que não funciona para pesquisa específica

Estou tentando usar o findcomando para listar o tamanho de um determinado conjunto de arquivos, mas não estou obtendo saída. O comando que uso é:

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

O que não produz saída. Enquanto:

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

produz saída, também tentei as ações:

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

mas tudo isso não fornece saída. Quando uso qualquer uma dessas ações com uma expressão diferente, por exemplo:

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

Eu também recebo o resultado esperado. Alguém tem alguma ideia de qual é o problema? Estou correndo:

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

também conhecida como distribuição Linux Manjaro atualizada. O shell que uso é: /bin/bashversion 4.3.8(1)-release.

O conteúdo da minha SHELLOPTSvariável de ambiente é:

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

minha BASHOPTSvariável de ambiente é:

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

Novamente, qualquer ajuda para tentar depurar isso seria muito apreciada.

Responder1

Há uma armadilha com oe/oupalavras-chave em find. oraplicado a todos os parâmetros a seguir, incluindo a ação ( -lsno seu exemplo). andexpressões sem or(ou anexadas com and) são avaliadas em ordem de leitura com uma parada final como falsa. Não há implicit ().

Portanto, o comando find POD -type f -name *.mp3 -or -name *.ogg -lssignifica,

  • procure (começando no diretório POD) por arquivos --- se nenhum arquivo for encontrado: STOP
  • else (arquivo encontrado) verifique a correspondência de padrões *.mp3 --- se a correspondência de padrões: STOP! (porque ORaplicado a partir daqui e somente se o comando anterior falhou (mas apenas o comando anterior, não os grupos de comando anteriores)

e como você adiciona uma instrução de execução ( -ls, -exec, -print....) na linha de comando, não há -printcomando implícito e, portanto, nada para executar se 1) todas as condições de 1) forem verdadeiras (arquivo e padrão correspondidos). Se você remover o último, -lshaverá uma distribuição implícita -printno final de cada condição.

  • caso contrário, se o padrão não corresponder, procure por qualquer coisa (arquivo/diretório) que corresponda ao padrão *.ogge liste-os (o -lsnão é um comando de condição, é executado apenas se o comando/teste "padrão" anterior *.oggfor verdadeiro). Mas por causa de 1), 2) é avaliado apenas para arquivos NÃO mp3. Se você não tiver .oggarquivos, não verá nada.

Solução 1 repita o comando de execução em cada ramificação lógica

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

Solução 2add (protegido pelo shell) parênteses

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

Observação você deve proteger os padrões para evitar a avaliação de padrões de shell no diretório atual.

Responder2

Acho que é por causa da ordem de avaliação (falta de precedência explícita), por exemplo, se

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

então, se -name '*.ogg'for avaliado como falso, a lsação não será executada. Você pode obter o comportamento esperado agrupando suas expressões OR usando parênteses - por exemplo, se

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

Então

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

enquanto

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

não produz saída. Observe que

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

é um caso especial porque é implicitamente tratado como

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

Observe também que é uma boa prática citar ou escapar dos globs do shell em um findcomando para evitar que o shell os expanda - consulte a NON-BUGSseção da página de manual find.

informação relacionada