
Eu tenho alguns arquivos duplicados em diretórios A
e B
como posso excluir os ingênuos B
usando os nomes de arquivos A
do bash?
Como fazer isso em outros shells é um bônus bem-vindo.
Responder1
Mão Única:
#!/bin/bash
cd ~/B
for file in ~/A/*
do
file1=$(basename "$file")
[ -f "$file1" ] && { echo "deleting $file1 "; rm -- "$file1"; }
done
Responder2
Em uma linha
grep -f <(ls "A") <(ls "B") | xargs -I'{}' rm "B/{}"
mas funciona depende apenas do nome do arquivo e pode afetar subdiretórios vazios. Para evitar isso, use find -type f -maxdepth 1
em vez de ls
.
Para uma verificação mais segura, use o recibo @KasyA.
Responder3
find /path/to/dirA -type f -exec cmp -s '{}' '/path/to/dirB/{}' \; -exec echo rm -v '/path/to/dirB/{}' \;
Em um teste:
$ 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: remova echo
o que é usado para simulação.
Responder4
cd B
ls ../
A
B
comm <(ls ../A) <(ls ./) -1 -2 -z | xargs -0 rm
comm
mostra três colunas,
- exclusivo para arquivo1 (A)
- exclusivo para arquivo2 (B)
- existem em ambos
Então eliminamos a coluna 1, 2 por -1 -2
. -z
usaria NULL para delimitador. O padrão é `\n' nova linha.
Ao lidar com pipe e lista de strings arbitrárias como nome de arquivo, a transferência delimitada por NULL é segura.