Respuestas:
Editar: Si bien la siguiente respuesta explica el caso de uso general, debo tener en cuenta que eliminar archivos y directorios es un caso especial. En lugar de usar la -execdir rm {} \;
construcción, simplemente use -delete
, como en:
find -iname '*.txt' -delete
Esto maneja un montón de casos extremos en los que podría no pensar, incluido el orden de los archivos y directorios que deben eliminarse para no encontrarse con errores. Para otros casos de uso ...
La mejor manera de manejar los comandos en ejecución de los resultados de un hallazgo es usualmente usar las diversas -exec
opciones para el find
comando. En particular, debe intentar usarlo -execdir
siempre que sea posible, ya que se ejecuta dentro del directorio del archivo que se encontró y generalmente es más seguro (en el sentido de evitar que los errores estúpidos sean desastrosos) que otras opciones.
Las -exec
opciones son seguidas por el comando que le gustaría ejecutar con {}
denotar el lugar donde se debe incluir el archivo encontrado por find y se termina ya sea \;
para ejecutar el comando una vez para cada archivo o +
para reemplazarlo {}
con una lista de argumentos de todas las coincidencias . Tenga en cuenta que el terminador de punto y coma se escapa para que el shell no lo entienda como un separador que conduce a un nuevo comando.
Digamos que estaba encontrando todos los archivos de texto:
find -iname '*.txt' -execdir rm {} \;
Aquí está el bit relevante del manual de búsqueda ( man find
):
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command until
an argument consisting of ‘;’ is encountered. The string ‘{}’
is replaced by the current file name being processed everywhere
it occurs in the arguments to the command, not just in arguments
where it is alone, as in some versions of find. Both of these
constructions might need to be escaped (with a ‘\’) or quoted to
protect them from expansion by the shell. See the EXAMPLES sec-
tion for examples of the use of the -exec option. The specified
command is run once for each matched file. The command is exe-
cuted in the starting directory. There are unavoidable secu-
rity problems surrounding use of the -exec action; you should
use the -execdir option instead.
-exec command {} +
This variant of the -exec action runs the specified command on
the selected files, but the command line is built by appending
each selected file name at the end; the total number of invoca-
tions of the command will be much less than the number of
matched files. The command line is built in much the same way
that xargs builds its command lines. Only one instance of ‘{}’
is allowed within the command. The command is executed in the
starting directory.
-execdir command ;
-execdir command {} +
Like -exec, but the specified command is run from the subdirec-
tory containing the matched file, which is not normally the
directory in which you started find. This a much more secure
method for invoking commands, as it avoids race conditions dur-
ing resolution of the paths to the matched files. As with the
-exec action, the ‘+’ form of -execdir will build a command line
to process more than one matched file, but any given invocation
of command will only list files that exist in the same subdirec-
tory. If you use this option, you must ensure that your $PATH
environment variable does not reference ‘.’; otherwise, an
attacker can run any commands they like by leaving an appropri-
ately-named file in a directory in which you will run -execdir.
The same applies to having entries in $PATH which are empty or
which are not absolute directory names.
Una alternativa es canalizar la salida y analizarla con comandos posteriores. La única forma segura de hacerlo es usar la -print0
opción, que le indica find
que use un carácter nulo como delimitador de resultados. Los comandos de recepción deben tener la capacidad de reconocer entradas delimitadas nulas. Ejemplo:
find /home/phunehehe -iregex '.*\.png$' -print0 | xargs -0 file
Tenga en cuenta que la -0
opción le dice xargs
que trate la entrada como nula delimitada.
-exec
con más archivos si lo termina con en +
lugar de ;
. Ver la respuesta de Caleb.
Estaba buscando una respuesta a esto y me topé con este hilo. Las respuestas me dieron una idea de cómo podría lograrlo. Supongamos que desea encontrar el mediainfo
de todos los archivos JPEG
Esto se agregaría mediainfo "
al principio y "
al final de cada archivo coincidente (para escapar de caracteres especiales tanto como sea posible), póngalo en un script y ejecute el script:
find . -name *.jpg | sed -e 's/^/mediainfo "/g;' | sed -e 's/$/"/g;' > foo.sh && sh foo.sh
En caso de que le preocupe que algo pueda salir mal, puede omitir la redirección de la salida a un archivo y simplemente ver el resultado en el terminal antes de ejecutar el script.
Puede lograr esto usando el xargs
comando. xargs
esencialmente ejecuta un comando una vez para cada instrucción de su entrada estándar. Entonces, si necesita eliminar todos los .jpg
archivos en un directorio, por ejemplo, una forma rápida en la línea de comando es:
$ find ./ -name "*.jpg" | xargs rm
También puede usar la tecla de retroceso (encima del botón Tabulador) para hacer esto (tenga en cuenta que este es el carácter de comilla inversa, no el carácter de comilla simple):
$ rm `find ./ -name "*.jpg"`
Tenga en cuenta que debido a la forma en que los xargs
shells procesan su entrada, el método xargs solo funciona si ninguno de los nombres de archivos y directorios involucrados contiene espacios en blanco o alguno de ellos \"'
; el método de comillas inversas solo funciona si ninguno de los nombres de archivos y directorios involucrados contiene espacios en blanco o alguno de ellos \[?*
.
find
, para lo cual -exec
generalmente es una mejor solución. Si desea especificarlos como alternativos, al menos explique cómo usarlos find -print0 | xargs -0
para el manejo seguro de la ruptura del nombre de archivo y explique cuándo tener cuidado con los backticks.