buscar: no hacer nada, si no se especifica ningún archivo

buscar: no hacer nada, si no se especifica ningún archivo

Quiero llamar al uso finden algunos nombres de archivos.

find $(do_something to find filenames) -print0 | xargs -r0 ls -ld

Esto se rompe si $(do_something to find filenames)no devuelve nada: el comando de búsqueda comienza a realizar una búsqueda recursiva.

¿Hay alguna manera de indicarle a Find que no haga nada si no obtiene ningún nombre de archivo/nombre de directorio explícito como argumento?

Respuesta1

Con zsh, haría:

files=($(do_something to find filenames))
(($#files)) && find $files ...

Con tcsh:

set files=(`do_something to find filenames`)
if ($#files) find $files:q ...

Con o bash,​mkshksh93

set -f; files=($(do_something to find filenames))
((${#files[@]})) && find "${files[@]}" ...

POSIXly:

set -f; set -- $(do_something to find filenames)
[ "$#" -gt 0 ] && find "$@" ...

(en bash y otros shells POSIX, $(...)se divide (en $IFS: espacio, tabulación y nueva línea de forma predeterminada), pero también realiza globbing en las palabras resultantes, lo cual no espero que quieras aquí, de ahí el set -f. Otros shells ((t)csh , zsh, fish, rc, es...) no tienes ese problema).

Respuesta2

¿Qué tal hacer esto?

paths=$(do_something to find filenames)
if [ "$paths" ]; then
    find "$paths" ...
fi

Esto funciona independientemente de la findimplementación.

Tenga en cuenta que find "$paths"tener más de un nombre de ruta causa problemas. Si los nombres de las rutas no contienen espacios, puede usar: find $paths; de lo contrario, una alternativa funcional es esta función:

dofind() {
    set -f
    set -- $(do_something to find filenames)
    if [ $# -gt 0 ]; then
        find "$@" ...
    fi
    set +f
}

Deshabilita la acumulación de archivos y luego los usa set --para configurar el vector arg de shells. Esto funciona con cualquier shell POSIX.

Respuesta3

Puede proporcionar findun directorio adicional inexistente para comenzar:

find " " $(do_something to find filenames) -print0 | xargs -r0 ls -ld

Para que esto esté ordenado, elimine findla salida de error:

find " " $(do_something to find filenames) -print0 2>/dev/null | xargs -r0 ls -ld

(pero luego no notarás si ocurre otro error...).

Cuando do_something to find filenamesgenere nombres de archivos, findse quejará " "pero aún procesará el resto de la línea de comando. Cuando no se genere ningún nombre de archivo, findvolverá a quejarse " "pero no agregará su archivo predeterminado ..

Respuesta4

En zsh(y en la mayoría de los shells no derivados de Bourne), cuando un (otododependiendo del caparazón)globono se expande, el comando se cancela.

$(do_something to find filenames)no es un globo, pero puedes convertirlo en uno agregando un calificador de globo en zsh:

 find $(do_something to find filenames)(#q) -print0...

Arriba, eso (#q)(un calificador global vacío, por lo que no hace nada más) se agrega a la última palabra resultante de la división de la salida de do_something to find filenames, por lo que el comando se cancelará si ese comando no produce salida (o en blanco), pero también si eso La última palabra (y solo esa última palabra) no se resuelve en una ruta existente. Puede hacer que se aplique a cada palabra resultante de esa división (para que el comando se cancele si alguna de esas palabras no se resuelve en un archivo existente) con:

 find ${^$(do_something to find filenames)}(#q) -print0...

información relacionada