acha que a ação não está funcionando para uma pesquisa específica [duplicada]

0

Estou tentando usar o comando find para listar o tamanho de um determinado conjunto de arquivos, mas não obtenho nenhuma saída. O comando que eu uso é:

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

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 todos estes não dão saída. Quando eu 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 a saída esperada. Alguém tem alguma idéia do que é 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 é uma distribuição atualizada do Manjaro Linux. O shell que eu uso é: /bin/bash version 4.3.8(1)-release .

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

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

minha variável de ambiente BASHOPTS é:

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

Novamente, qualquer ajuda sobre como tentar depurar isso seria muito apreciada.

    
por Bas Bossink 14.05.2014 / 22:22

2 respostas

1

Existe uma armadilha com as palavras-chave e / ou em find . or aplicado a todos os parâmetros a seguir, incluindo a ação ( -ls em seu exemplo). As expressões and sem or (ou anexadas com and ) são avaliadas na ordem de leitura com uma parada final como falsa. Não há implicit () .

Então o comando find POD -type f -name *.mp3 -or -name *.ogg -ls significa,

  • pesquisa (iniciando no diretório POD) para arquivos --- se nenhum arquivo foi encontrado: STOP
  • else (arquivo encontrado) padrão de verificação que corresponde a *.mp3 --- se combinar com o padrão: PARE! (porque OR aplicado aqui e somente se o comando anterior falhou (mas apenas o comando anterior, não os grupos de comando anteriores)

e porque você adiciona uma instrução de execução ( -ls , -exec , -print ....) na linha de comando, não há comando -print implícito e, portanto, nada a ser executado se 1) todas as condições de 1) são verdadeiras (arquivo e padrão combinados). Se você remover o último -ls , haverá um implícito -print distribuído no final de cada condição.

  • else se o padrão não corresponder à pesquisa por nada (arquivo / diretório) que corresponda ao padrão *.ogg e liste-os (o comando -ls não é uma condição, será executado apenas se o comando / teste anterior "pattern *.ogg é true) .Mas por causa de 1), 2) é avaliado apenas para arquivos MP3 NÃO Se você não tem arquivos .ogg você não vê 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 2 adicionar parêntesis (protegidos por shell)

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

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

    
por 14.05.2014 / 23:11
0

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

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

se -name '*.ogg' avaliar false, a ação ls 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. Note que

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

é um caso especial porque é implicitamente tratado como

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

Note também que é uma boa prática citar ou escapar de globs de shell em um comando find para evitar que o shell os expanda - veja a seção NON-BUGS da página de manual find.

    
por 14.05.2014 / 22:48