
Tengo algunos archivos duplicados en directorios A
y B
, ¿cómo podría eliminar los duplicados al B
usar los nombres de archivos A
en bash?
Cómo hacerlo en otros shells es un bono de bienvenida.
Respuesta1
De una sola mano:
#!/bin/bash
cd ~/B
for file in ~/A/*
do
file1=$(basename "$file")
[ -f "$file1" ] && { echo "deleting $file1 "; rm -- "$file1"; }
done
Respuesta2
en una linea
grep -f <(ls "A") <(ls "B") | xargs -I'{}' rm "B/{}"
pero su funcionamiento depende únicamente del nombre del archivo y puede afectar a los subdirectorios vacíos. Para evitar este uso find -type f -maxdepth 1
en lugar de ls
.
Para una comprobación más segura, utilice la receta @KasyA.
Respuesta3
find /path/to/dirA -type f -exec cmp -s '{}' '/path/to/dirB/{}' \; -exec echo rm -v '/path/to/dirB/{}' \;
En una prueba:
$ ls -1 /path/to/dirA
dupfile
file1inA
$ ls -1 /path/to/dirB
dupfile
file1inB
find /path/to/dirA -type f -exec cmp -s '{}' '/path/to/dirB/{}' \; -exec echo rm -v '/path/to/dirB/{}' \;
rm -v /path/to/dirB/./dupfile
nota: retire echo
el que se utiliza para el funcionamiento en seco.
Respuesta4
cd B
ls ../
A
B
comm <(ls ../A) <(ls ./) -1 -2 -z | xargs -0 rm
comm
muestra tres columnas,
- exclusivo del archivo 1 (A)
- exclusivo del archivo 2 (B)
- existen en ambos
Entonces eliminamos las columnas 1, 2 por -1 -2
. -z
usaría NULL como delimitador. El valor predeterminado es `\n' nueva línea.
Cuando se trata de canalizaciones y listas de cadenas arbitrarias como nombres de archivos, la transferencia delimitada por NULL es segura.