variable '-name' primário para 'find'

1

Estou tentando construir um composto -name primary para o comando find de um número arbitrário de sequências em uma matriz, na forma \( -name ${a[0]} -or -name ${a[1]} -or -name ${a[2]} ... \) . Enquanto explicitamente digita o nome primário no terminal funciona, armazená-lo em uma variável e recuperá-lo por expansão de parâmetro não. Como a expansão ocorrerá antes que find seja executado, presumo que o problema tenha algo a ver com a citação da variável expandida.

Abaixo está um exemplo mínimo para n = 2 nomes, digitados literalmente ou recuperados de uma variável. Enquanto eu percebo que eu poderia canalizar para grep , eu preferiria fazer tudo com find neste caso.

$ ls
a1  a2  b1  b2  c1  c2

$ find . \( -name a\* -or -name b\* \)
./a1
./a2
./b1
./b2

$ names="\( -name a\* -or -name b\* \)"

$ printf "%s\n" "$names"
\( -name a\* -or -name b\* \)

$ find . $(printf "%q" "$names")
find: -name\: unknown primary or operator

$ find . $(printf "%s" "$names")
find: \): unknown primary or operator

$ find . $names
find: \): unknown primary or operator

$ find . "$names"
find: \( -name a\* -or -name b\* \): No such file or directory
    
por user001 17.07.2018 / 23:19

1 resposta

2

Cada -name , cada -or , cada parênteses e cada padrão deve ser um argumento separado para find . Não concatene os argumentos com espaços intermediários: você não pode voltar para uma lista de argumentos - como você poderia saber quais espaços existem para separar argumentos e quais espaços são parte de um argumento? Veja também Por que meu shell script sufocar no espaço em branco ou outros caracteres especiais?

Se o seu shell suportar matrizes (ksh, bash, zsh), armazene a lista de argumentos em uma matriz.

names=(\( -name a\* -or -name b\* \))
…
find "${names[@]}"

Se o seu shell não suporta arrays, você pode construir a lista nos argumentos posicionais (os argumentos que você pode acessar como $1 , $2 ,…). A limitação óbvia é que você não pode usar os argumentos posicionais para outro propósito.

set -- \( -name a\* -or -name b\* \)
…
find "$@"
    
por 17.07.2018 / 23:25