Como excluir arquivos duplicados com base no padrão (veja os exemplos abaixo) usando um script ou um comando Bash

2

Minha pergunta é simples:

Eu tenho arquivos de vídeo com o seguinte nome:

  • xxxx_yyy_720_3800.mp4
  • xxxx_yyy_720_8000.mp4

onde yyy pode variar em comprimento (por exemplo, yyyyyy ou mais y)

Como não sou usado em scripts de shell, gostaria de excluir automaticamente (em uma pasta especificada)

  • Se houver um arquivo com o nome xxx_yyy_720_3800.mp4 e se o arquivo xxx_yyy_720_8000.mp4 existir, exclua xxx_yyy_720_3800.mp4
  • Se houver apenas um arquivo xxx_yyy_720_8000.mp4 e não um arquivo xxx_yyy_720_3800.mp4 , não faça nada.

Qualquer ajuda seria muito apreciada.

    
por Laurent06000 14.07.2015 / 18:22

2 respostas

1

Usando find e gawk

  1. Instale gawk

    sudo apt-get install gawk
    
  2. Entre na sua pasta ou substitua o . após o comando find pelo seu nome de pasta, por exemplo: find ~/my_video_duplicates f -iname …

  3. Teste o comando

    O comando abaixo mostra apenas os candidatos remover

    find . -type f -iname "*_8000.mp4" -print0 | \
        while read -d $'
    find . -type f -iname "*_8000.mp4" -print0 | \
        while read -d $'
    % ls -og
    total 3
    -rw-rw-r-- 1 0 Jul 14 19:37 xxxx_yyy_720_3800.mp4
    -rw-rw-r-- 1 0 Jul 14 19:20 xxxx_yyy_720_8000.mp4
    -rw-rw-r-- 1 0 Jul 14 19:21 aaaa_yyy_720_8000.mp4
    
    ' file; do \ gawk -F_ '{ \ a=gensub(/\_8000\./, "_3800.", "g" , $0); \ system("if [ -f \""a"\" ]; then rm \""a"\"; fi")}' <<< "$file";\ done
    ' file; do \ gawk -F_ '{ \ a=gensub(/\_8000\./, "_3800.", "g" , $0); \ system("if [ -f \""a"\" ]; then echo \""a"\" will be deleted; fi")}' <<< "$file";\ done
  4. Verifique novamente se você está na pasta correta ou substitua o . após o comando find pelo seu nome de pasta, por exemplo: find ~/my_video_duplicates f -iname …

  5. Se tiver certeza, execute o comando abaixo

    % find . -type f -iname "*_8000.mp4" -print0 | \
        while read -d $'
    % find . -type f -iname "*_8000.mp4" -print0 | \
        while read -d $'
    % ls -og
    total 2
    -rw-rw-r-- 1 0 Jul 14 19:20 xxxx_yyy_720_8000.mp4
    -rw-rw-r-- 1 0 Jul 14 19:21 aaaa_yyy_720_8000.mp4
    
    ' file; do \ gawk -F_ '{ \ a=gensub(/\_8000\./, "_3800.", "g" , $0); \ system("if [ -f \""a"\" ]; then rm \""a"\"; fi")}' <<< "$file";\ done
    ' file; do \ gawk -F_ '{ \ a=gensub(/\_8000\./, "_3800.", "g" , $0); \ system("if [ -f \""a"\" ]; then echo \""a"\" will be deleted; fi")}' <<< "$file";\ done ./xxxx_yyy_720_3800.mp4 will be deleted

Exemplo

  • A situação inicial

    sudo apt-get install gawk
    
  • A corrida a seco

    find . -type f -iname "*_8000.mp4" -print0 | \
        while read -d $'
    find . -type f -iname "*_8000.mp4" -print0 | \
        while read -d $'
    % ls -og
    total 3
    -rw-rw-r-- 1 0 Jul 14 19:37 xxxx_yyy_720_3800.mp4
    -rw-rw-r-- 1 0 Jul 14 19:20 xxxx_yyy_720_8000.mp4
    -rw-rw-r-- 1 0 Jul 14 19:21 aaaa_yyy_720_8000.mp4
    
    ' file; do \ gawk -F_ '{ \ a=gensub(/\_8000\./, "_3800.", "g" , $0); \ system("if [ -f \""a"\" ]; then rm \""a"\"; fi")}' <<< "$file";\ done
    ' file; do \ gawk -F_ '{ \ a=gensub(/\_8000\./, "_3800.", "g" , $0); \ system("if [ -f \""a"\" ]; then echo \""a"\" will be deleted; fi")}' <<< "$file";\ done
  • A remoção

    % find . -type f -iname "*_8000.mp4" -print0 | \
        while read -d $'
    % find . -type f -iname "*_8000.mp4" -print0 | \
        while read -d $'
    % ls -og
    total 2
    -rw-rw-r-- 1 0 Jul 14 19:20 xxxx_yyy_720_8000.mp4
    -rw-rw-r-- 1 0 Jul 14 19:21 aaaa_yyy_720_8000.mp4
    
    ' file; do \ gawk -F_ '{ \ a=gensub(/\_8000\./, "_3800.", "g" , $0); \ system("if [ -f \""a"\" ]; then rm \""a"\"; fi")}' <<< "$file";\ done
    ' file; do \ gawk -F_ '{ \ a=gensub(/\_8000\./, "_3800.", "g" , $0); \ system("if [ -f \""a"\" ]; then echo \""a"\" will be deleted; fi")}' <<< "$file";\ done ./xxxx_yyy_720_3800.mp4 will be deleted
  • A situação final

    %pre%
por A.B. 14.07.2015 / 19:36
1

Usando o Bash Shell

[ -f "file" ] verifica se existe um nome de arquivo e é um arquivo comum (por exemplo, não é um diretório ou um link simbólico)

"${name/%x/y}" substitui o sufixo x de $name por y .

Portanto, para excluir xxx_yyy_720_3800.mp4 somente se existir xxx_yyy_720_8000.mp4 , onde xxx e yyy são idênticos em cada caso, for all *_*_720_3800.mp4 in o diretório atual:

for name in *_*_720_3800.mp4
do if [ -f "${name/%3800.mp4/8000.mp4}" ]
   then echo "$name"
   fi
done

Altere o echo para rm se tiver certeza de que está tudo bem.

    
por Martin Thornton 14.07.2015 / 20:30