4 votes

Un utilitaire pour trouver les dossiers en double (PAS les fichiers)

Je suis au courant rdfind qui peut trouver les fichiers en double dans deux répertoires. Mais j'ai besoin d'un utilitaire similaire qui trouve les dossiers en double (dossiers qui ont le même nom et le même chemin par rapport aux répertoires principaux) dans deux répertoires principaux. Existe-t-il un utilitaire capable de réaliser cette tâche simple ?

**Example:**
$ tree
.
 maindir1
    dir space
       dir1
       dir2
    dir1
    dir2
       new\012line
    dir3
       dir5
    dir4
        dir6
 maindir2
    dir space
       dir2
    dir1
    dir2
       new\012line
    dir5
       dir6
    dir6
    new\012line
 file
 new\012line

NOTA: Dans l'exemple ci-dessus, les seuls dossiers dupliqués au premier niveau (profondeur 1) sont :

maindir1/dir space/ & maindir2/dir space/
maindir1/dir1/ & maindir2/dir1/
maindir1/dir2/ & maindir2/dir2/

Au deuxième niveau (profondeur 2), les seuls dossiers dupliqués sont :

maindir1/dir space/dir2/ & maindir2/dir space/dir2/
maindir1/dir2/new\012line/ & maindir2/dir2/new\012line/

Veuillez noter que maindir1/dir3/dir5/ y maindir2/dir5/ sont no les doublons et aussi maindir1/dir4/dir6/ y maindir2/dir5/dir6/ sont no les doublons.

3voto

Stewart Points 1385

Je ne connais pas d'utilitaire qui soit spécifique aux répertoires (mais des choses comme fslint o fdupes devrait auch liste des répertoires) mais il est assez facile de script :

#!/usr/bin/env bash

## Declare $dirs and $count as associative arrays
declare -A dirs
declare -A count

find_dirs(){
    ## Make ** recurse into subdirectories
    shopt -s globstar
    for d in "$1"/**
    do
    ## Remove the top directory from the dir's path
    dd="${d#*/}"
    ## If this is a directory, and is not the top directory
    if [[ -d "$d" && "$dd" != "" ]]
    then
        ## Count the number of times it's been seen
        let count["$dd"]++
        ## Add it to the list of paths with that name.
        ## I am using the `&` to separate directory entries
        dirs["$dd"]="${dirs[$dd]} & $d" 
    fi

    done
}

## Iterate over the list of paths given as arguments
for target in "$@"
do
    ## Run the find_dirs function on each of them
    find_dirs "$target"
done

## For each directory found by find_dirs
for d in "${!dirs[@]}"
do
    ## If this name has been seen more than once
    if [[ ${count["$d"]} > 1 ]]
    then
    ## Print the name with pretty colors
    printf '\033[01;31m+++ NAME: "%s" +++\033[00m\n' "$d"
    ## Print the paths with that name
    printf "%s\n" "${dirs[$d]}" | sed 's/^ & //'
    fi
done

Le script ci-dessus peut traiter des noms de répertoires arbitraires (y compris ceux avec des espaces ou même des nouvelles lignes dans leurs noms) et fera une récursion dans un nombre quelconque de sous-répertoires. Par exemple, sur cette structure de répertoire :

$ tree
.
 maindir1
    dir1
    dir2
       new\012line
    dir3
       dir5
    dir4
       dir6
    dir space
        dir1
        dir2
 maindir2
     dir1
     dir2
        new\012line
     dir5
        dir6
     dir6
     dir space
        dir2
     new\012line

Il retournera ceci :

Screenshot showing the script's output

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X