Comando como este:
find /directory -type f -name "*.txt" -print | xargs rm
elimine todos .txt
los archivos en el directorio y subdirectorios, y eso está bien. Pero, si creamos una variable o matriz para la extensión del archivo y luego ponemos find
, por ejemplo,
TXT=(*.txt)
for ii in ${TXT[@]}; do
find /directory -type f -name $TXT -print | xargs rm
done
Estos comandos no eliminan .txt
archivos en subdirectorios. ¿Por qué? ¿Cómo cambiar este segundo código para eliminar archivos en subdirectorios?
PD: utilicé una matriz porque tengo más de una extensión de archivo.
Respuesta1
Su asignación de matriz,
TXT=(*.txt)
expandirá el *.txt
patrón a la lista de nombres de archivos en el directorio actual que coincida con ese patrón. El caparazón haría esto en el momento de la asignación. Esto no es lo que quieres. Quieres dar find
la cadena literal *.txt
, así:
pattern='*.txt'
find /directory -type f -name "$pattern" -exec rm {} +
xargs rm
Aquí, también me deshice rm
de find
. La mayoría de las implementaciones actuales find
podrían utilizar el estándar no estándar -delete
en lugar de -exec rm {} +
:
pattern='*.txt'
find /directory -type f -name "$pattern" -delete
Tenga en cuenta que no hay necesidad de un bucle aquí ya que solo estamos tratando con un patrón único. También tenga en cuenta que citar "$pattern"
en la llamada a find
es importante; de lo contrario, el patrón sería reemplazado por todos los nombres de archivos coincidentes en el directorio actual antes de find
comenzar.
Para varios patrones, puedes hacer un bucle como este:
patterns=( '*.txt' '*.tmp' )
for pattern in "${patterns[@]}"; do
find /directory -type f -name "$pattern" -delete
done
Las comillas en la asignación de la matriz son esenciales ya que evitan que el shell use los patrones como patrones globales de nombres de archivos en ese momento. La cita de "${patterns[@]}"
y "$pattern"
es igualmente importante, por la misma razón.
Otro método es realizar una sola llamada a find
, incluso si tiene varios patrones. Esto aceleraría bastante las cosas si /directory
se trata de una jerarquía de directorios grande. El siguiente código lo hace creando una serie de -name
pruebas para find
su uso:
patterns=( '*.txt' '*.tmp' )
name_tests=( )
for pattern in "${patterns[@]}"; do
name_tests+=( -o -name "$pattern" )
done
# "${name_tests[@]:1}" removes the initial "-o", which shouldn't be there.
name_tests=( '(' "${name_tests[@]:1}" ')' )
find /directory -type f "${name_tests[@]}" -delete
En el script anterior, el comando real ejecutado al final será
find /directory -type f '(' -name '*.txt' -o -name '*.tmp' ')' -delete
... que eliminará todos los archivos normales que tengan sufijos de nombre de archivo.txt
o .tmp
en cualquier lugar dentro o debajo del directorio /directory
.