removendo arquivos duplicados em pares

1

Eu tenho cerca de 700 pastas. Cada pasta contém combinações de arquivos em pares. Gostaria de reter apenas um arquivo por combinação de pares. Qualquer um dos arquivos emparelhados pode ser retido, pois ambos contêm o mesmo conteúdo. Os arquivos na pasta não são necessariamente nomeados em ordem alfabética.

  Example: 
      Folder1: 
        -> A-B.txt
        -> B-A.txt

      Folder2: 
        -> C-D.txt
        -> C-E.txt
        -> E-C.txt
        -> D-E.txt
        -> D-C.txt
        -> E-D.txt

     Final folder structure: 
         Folder1: 
               -> A-B.txt (or) B-A.txt
         Folder2: 
               -> C-D.txt (or) D-C.txt
               -> C-E.txt (or) E-C.txt
               -> D-E.txt (or) E-D.txt
    
por biobudhan 17.03.2017 / 11:18

3 respostas

2

Você poderia fazer algo como

  ls *.txt | awk -F '[.-]' '{ if (f[$2,$1]) { print $0; }
                              else { f[$1,$2] = 1} }' | xargs rm

Isso funciona da seguinte maneira: alimente os nomes dos arquivos relevantes para awk . Para cada arquivo, verifique se um arquivo com nome invertido já foi inserido na matriz f . Em caso afirmativo, imprima o nome do arquivo. Caso contrário, coloque-o no array f . Use a saída do programa awk para excluir os arquivos duplicados.

    
por 17.03.2017 / 12:04
0

Você pode usar find e extrair as partes antes e depois do traço do nome do arquivo, testando se o par existe e removendo o respectivo arquivo:

find . -name \*-\*.txt -execdir sh -c 'fn=${1##*/};bn=${fn%.*};one=${bn%-*};
two=${bn#*-};pair=${two}-${one}.txt; [[ -f $pair ]] && rm "$1"' boom {} \;

O mesmo pode ser feito com um loop for (e supondo que o shell suporte globalização recursiva):

# if you're using bash run
shopt -s globstar

então

for f in **/*-*.txt; do
dn=${f%/*}; fn=${f##*/}; bn=${fn%.*}; one=${bn%-*}; two=${bn#*-};
pair=${dn}/${two}-${one}.txt; [[ -f $pair ]] && rm -- "$f"; done
    
por 17.03.2017 / 12:54
0
find . -type d -exec \
   perl -wMstrict -le '
      (local $", my $top) = ("", $ENV{PWD});
      for my $curdir ( @ARGV ) {
         my %h;
         chdir $curdir;
            for ( <*.txt> ) {
               my @pair = /^([^-]+)-([^.]+)[.]txt$/;
               next unless @pair;
               $h{ "@pair" }++;
               unlink if exists $h{ "@{[reverse @pair]}" };
            }
         chdir $top;
      }
   ' {} +

sed

/bin/ls -1 |
sed -ne '
   1H;1d
   G
   /^\([^-]*\)-\([^.]*\).txt\n\(.*\n\)\{0,1\}-.txt$/P
   /^\([^-]*\)-\([^.]*\).txt\n\(.*\n\)\{0,1\}-.txt\n/P
   s/\n\n.*//;H
' | xargs rm
    
por 17.03.2017 / 14:13