encontrar xargs rm con patrón de nombre de archivo en variable

encontrar xargs rm con patrón de nombre de archivo en variable

Comando como este:

find /directory -type f -name "*.txt" -print | xargs rm

elimine todos .txtlos 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 .txtarchivos 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 *.txtpatró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 findla cadena literal *.txt, así:

pattern='*.txt'
find /directory -type f -name "$pattern" -exec rm {} +

xargs rmAquí, también me deshice rmde find. La mayoría de las implementaciones actuales findpodrían utilizar el estándar no estándar -deleteen 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 findes importante; de ​​lo contrario, el patrón sería reemplazado por todos los nombres de archivos coincidentes en el directorio actual antes de findcomenzar.

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 /directoryse trata de una jerarquía de directorios grande. El siguiente código lo hace creando una serie de -namepruebas para findsu 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 .tmpen cualquier lugar dentro o debajo del directorio /directory.

información relacionada