Quero chamar use find
em alguns nomes de arquivos.
find $(do_something to find filenames) -print0 | xargs -r0 ls -ld
Isso é interrompido se $(do_something to find filenames)
não retornar nada: o comando find começa a fazer uma pesquisa recursiva.
Existe uma maneira de dizer ao find para não fazer nada se não obtiver nenhum nome de arquivo/nome de diretório explícito como argumento?
Responder1
Com zsh
, eu faria:
files=($(do_something to find filenames))
(($#files)) && find $files ...
Com tcsh
:
set files=(`do_something to find filenames`)
if ($#files) find $files:q ...
Com bash
, mksh
ou ksh93
,
set -f; files=($(do_something to find filenames))
((${#files[@]})) && find "${files[@]}" ...
POSIXamente:
set -f; set -- $(do_something to find filenames)
[ "$#" -gt 0 ] && find "$@" ...
(no bash e em outros shells POSIX, $(...)
divide (em $IFS
: espaço, tabulação e nova linha por padrão), mas também executa globbing nas palavras resultantes que não espero que você queira aqui, portanto, o set -f
. Outros shells ((t)csh , zsh, fish, rc, es...) não tem esse problema).
Responder2
Que tal fazer isso:
paths=$(do_something to find filenames)
if [ "$paths" ]; then
find "$paths" ...
fi
Isso funciona independente da find
implementação.
Observe que find "$paths"
ter mais de um nome de caminho causa problemas. Se os nomes dos caminhos não contiverem espaços, você poderá usar: find $paths
, caso contrário, uma alternativa funcional é esta função:
dofind() {
set -f
set -- $(do_something to find filenames)
if [ $# -gt 0 ]; then
find "$@" ...
fi
set +f
}
Ele desativa o globbing de arquivos e, em seguida, usa set --
para definir o vetor arg dos shells. Isso funciona com qualquer shell POSIX.
Responder3
Você pode fornecer find
um diretório extra e inexistente para começar:
find " " $(do_something to find filenames) -print0 | xargs -r0 ls -ld
Para deixar isso organizado, descarte find
a saída de erro de:
find " " $(do_something to find filenames) -print0 2>/dev/null | xargs -r0 ls -ld
(mas você não notará se ocorrer outro erro...).
Quando do_something to find filenames
gerar nomes de arquivos, find
reclamará, " "
mas ainda processará o resto da linha de comando. Quando nenhum nome de arquivo for gerado, find
ele reclamará novamente, " "
mas não adicionará seu arquivo .
.
Responder4
Em zsh
(e na maioria dos shells não derivados de Bourne), quando um (outodosdependendo da casca)globonão se expande, o comando é abortado.
$(do_something to find filenames)
não é um glob, mas você pode torná-lo um anexando um qualificador glob em zsh
:
find $(do_something to find filenames)(#q) -print0...
Acima, isso (#q)
(um qualificador glob vazio, então não faz nada de outra forma) é anexado à última palavra resultante da divisão da saída de do_something to find filenames
, então o comando será abortado se esse comando não produzir saída (ou em branco), mas também se isso a última palavra (e apenas essa última palavra) não resolve um caminho existente. Você pode aplicá-lo a todas as palavras resultantes dessa divisão (para que o comando seja abortado se alguma dessas palavras não resolver para um arquivo existente) com:
find ${^$(do_something to find filenames)}(#q) -print0...