Quiero llamar al uso find
en 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
,mksh
ksh93
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 find
implementació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 find
un directorio adicional inexistente para comenzar:
find " " $(do_something to find filenames) -print0 | xargs -r0 ls -ld
Para que esto esté ordenado, elimine find
la 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 filenames
genere nombres de archivos, find
se quejará " "
pero aún procesará el resto de la línea de comando. Cuando no se genere ningún nombre de archivo, find
volverá 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...