2011-02-28 18 views
54

Tengo un archivo de texto largo con la lista de máscaras de archivos Quiero borrarUnix: Cómo borrar archivos que aparecen en un archivo

Ejemplo:

/tmp/aaa.jpg 
/var/www1/* 
/var/www/qwerty.php 

tengo que eliminarlos. Intentó rm ` cat 1.txt ` y dice que la lista es demasiado larga.

Encontré este comando, pero cuando reviso las carpetas de la lista, algunas de ellas todavía tienen archivos xargs rm <1.txt La llamada manual rm quita los archivos de dichas carpetas, por lo que no hay problema con los permisos.

+4

Aunque es seis años después: ¿Aceptarías una de las respuestas?Esto marcará la pregunta como resuelta y ayudará a otros usuarios también. – MERose

+0

@Alexander: debes tener la decencia y aceptar la respuesta preferida ya ... no solo sanguijuela en este foro. Veo que estuviste en línea ayer – Marius

Respuesta

11

xargs -I{} sh -c 'rm {}' < 1.txt debe hacer lo que desee. Tenga cuidado con este comando ya que una entrada incorrecta en ese archivo podría causar muchos problemas.

Esta respuesta se editó después de que @tdavies señaló que el original no tenía expansión de shell.

+0

Gracias, pero no hay necesidad de eliminar carpetas, solo archivos – Alexander

+1

Los globos no se expandirán, ya que nunca son 'vistos' por el caparazón. – tgdavies

+0

@tdavies wow - tienes razón. Este comando (aunque un poco más feo) funcionará: 'xargs -I {} sh -c 'rm {}' <1.txt' –

75

Esto no es muy eficiente, pero funcionará si necesita patrones globales (como en/var/www/*)

for f in $(cat 1.txt) ; do 
    rm "$f" 
done 

Si usted no tiene ningún patrón y está seguro de sus trayectorias en el de archivos no contienen espacios en blanco u otras cosas extrañas, puede utilizar xargs así:

xargs rm < 1.txt 
9

se puede usar esta sola línea:

cat 1.txt | xargs echo rm | sh 

¿Qué hace la expansión de shell pero ejecuta rm el número mínimo de veces.

+0

Siempre y cuando cualquier expansión no es demasiado largo? –

+1

Cierto, un globo podría producir una lista de argumentos que es demasiado larga: puede agregar el argumento '-n ' a 'xargs' para reducir el número de argumentos pasados ​​a cada rm, pero eso aún no lo protegerá de una solo glob que excede el límite. – tgdavies

0

Aquí usted puede utilizar un conjunto de carpetas de deletelist.txt mientras evitar algunos patrones así

foreach f (cat deletelist.txt) 
    rm -rf ls | egrep -v "needthisfile|*.cpp|*.h" 
end 
32

el supuesto de que la lista de archivos se encuentra en el archivo 1.txt, a continuación, hacer:

xargs rm -r <1.txt 

La opción -r causa recursividad en cualquier directorio llamado en 1.txt.

Si los archivos son de sólo lectura, utilice la opción -f a forzar la eliminación:

xargs rm -rf <1.txt 

Tenga cuidado con la entrada a cualquier herramienta que hace supresiones programáticos. Realice cierto que los archivos nombrados en el archivo de entrada realmente se deben eliminar. Tenga especial cuidado con los errores tipográficos aparentemente simples. Por ejemplo, si se introduce un espacio entre un archivo y su sufijo, que parecerá ser dos nombres de archivo diferentes:

file .txt 

es en realidad dos archivos separados: file y .txt.

Esto puede no parecer tan peligroso, pero si el error tipográfico es algo como esto:

myoldfiles * 

A continuación, en lugar de eliminar todos los archivos que comienzan con myoldfiles, podrás llegar a borrar myoldfiles y todo no -dot-files y directorios en el directorio actual. Probablemente no sea lo que querías.

+0

"myoldfiles /" o "/ tmp" aún más desastroso con -rf. Tenga en cuenta el carácter de espacio al lado de "/". – Ray

9

Utilice esta:

while read file ; do rm "$file" ; done < delete.list 

Si necesita expansión pegote se puede omitir citar $file:

while read file ; do rm $file ; done < delete.list 

Pero ten en cuenta que los nombres de archivo pueden contener contenido "problemático" y yo usaría el unquoted versión. Imagine ese patrón en el archivo

-rf * 

¡Esto eliminaría todo recursivamente en el directorio actual! Le recomendaría que prepare la lista de eliminación de manera que los patrones globales ya no sean necesarios, y luego use citando como en mi primer ejemplo.

1

En este caso particular, debido a los peligros citados en otras respuestas, lo haría

  1. Editar en, por ejemplo, Vim y :%s/\s/\\\0/g, escapando todos los caracteres de espacio con una barra diagonal inversa.

  2. Luego :%s/^/rm -rf /, anteponiendo el comando. Con -r no tiene que preocuparse de tener directorios enumerados después de los archivos que figuran en el mismo, y con -f no se quejará debido a la falta de archivos o entradas duplicadas.

  3. ejecutar los comandos: $ source 1.txt

1

He aquí otro ejemplo de bucle. Éste contiene también un 'sentencia if' como un ejemplo de la comprobación para ver si la entrada es un 'archivo' (o un 'directorio', por ejemplo):

for f in $(cat 1.txt); do if [ -f $f ]; then rm $f; fi; done 
6

que puedes usar '\ n' para define el nuevo carácter de línea como delimitador.

xargs -d '\n' rm < 1.txt 

tener cuidado con el rf, ya que puede eliminar lo que no quiere si el 1.txt contiene rutas con espacios. Es por eso que el delimitador de la nueva línea es un poco más seguro.

+1

En OS X esto me da 'xargs: opción ilegal - d' – waldyrious

+0

Buen punto. Parece que no hay otra opción que '-0' en OS X. – Ray

+2

' xargs -I_ rm _' también funciona en OS X :) ver http://stackoverflow.com/a/39335402/266309 – waldyrious

0

Esto permitirá que los nombres de los archivos tengan espacios (ejemplo reproducible).

# Select files of interest, here, only text files for ex. 
find -type f -exec file {} \; > findresult.txt 
grep ": ASCII text$" findresult.txt > textfiles.txt 
# leave only the path to the file removing suffix and prefix 
sed -i -e 's/:.*$//' textfiles.txt 
sed -i -e 's/\.\///' textfiles.txt 

#write a script that deletes the files in textfiles.txt 
IFS_backup=$IFS 
IFS=$(echo "\n\b") 
for f in $(cat textfiles.txt); 
do 
rm "$f"; 
done 
IFS=$IFS_backup 

# save script as "some.sh" and run: sh some.sh 
2

cat 1.txt | xargs rm -f | bash Ejecutar el comando hará lo siguiente solo para archivos.

cat 1.txt | xargs rm -rf | bash Ejecutar el comando hará el siguiente comportamiento recursivo.

Cuestiones relacionadas