¿Buscar nombres de archivos duplicados dentro de la jerarquía de carpetas?

22

Tengo una carpeta llamada img , esta carpeta tiene muchos niveles de subcarpetas, todas las cuales contienen imágenes. Los voy a importar a un servidor de imágenes.

Normalmente, las imágenes (o cualquier archivo) pueden tener el mismo nombre siempre que estén en una ruta de directorio diferente o tengan una extensión diferente. Sin embargo, el servidor de imágenes al que los estoy importando requiere que todos los nombres de las imágenes sean únicos (incluso si las extensiones son diferentes).

Por ejemplo, las imágenes background.png y background.gif no estarían permitidas porque, aunque tengan extensiones diferentes, todavía tienen el mismo nombre de archivo. Incluso si están en subcarpetas separadas, todavía deben ser únicos.

Así que me pregunto si puedo hacer una búsqueda recursiva en la carpeta img para encontrar una lista de archivos que tienen el mismo nombre (sin incluir la extensión).

¿Hay algún comando que pueda hacer esto?

    
pregunta JD Isaacks 13.06.2011 - 15:28

5 respuestas

15

FSlint es un buscador duplicado versátil que incluye una función para buscar nombres duplicados:

El paquete FSlint para Ubuntu enfatiza la interfaz gráfica, pero como se explica en la FAQ de FSlint a la interfaz de línea de comandos está disponible a través de los programas en /usr/share/fslint/fslint/ . Use la opción --help para la documentación, por ejemplo:

$ /usr/share/fslint/fslint/fslint --help
File system lint.
A collection of utilities to find lint on a filesystem.
To get more info on each utility run 'util --help'.

findup -- find DUPlicate files
findnl -- find Name Lint (problems with filenames)
findu8 -- find filenames with invalid utf8 encoding
findbl -- find Bad Links (various problems with symlinks)
findsn -- find Same Name (problems with clashing names)
finded -- find Empty Directories
findid -- find files with dead user IDs
findns -- find Non Stripped executables
findrs -- find Redundant Whitespace in files
findtf -- find Temporary Files
findul -- find possibly Unused Libraries
zipdir -- Reclaim wasted space in ext2 directory entries
$ /usr/share/fslint/fslint/findsn --help
find (files) with duplicate or conflicting names.
Usage: findsn [-A -c -C] [[-r] [-f] paths(s) ...]

If no arguments are supplied the $PATH is searched for any redundant
or conflicting files.

-A reports all aliases (soft and hard links) to files.
If no path(s) specified then the $PATH is searched.

If only path(s) specified then they are checked for duplicate named
files. You can qualify this with -C to ignore case in this search.
Qualifying with -c is more restictive as only files (or directories)
in the same directory whose names differ only in case are reported.
I.E. -c will flag files & directories that will conflict if transfered
to a case insensitive file system. Note if -c or -C specified and
no path(s) specifed the current directory is assumed.

Uso de ejemplo:

$ /usr/share/fslint/fslint/findsn /usr/share/icons/ > icons-with-duplicate-names.txt
$ head icons-with-duplicate-names.txt 
-rw-r--r-- 1 root root    683 2011-04-15 10:31 Humanity-Dark/AUTHORS
-rw-r--r-- 1 root root    683 2011-04-15 10:31 Humanity/AUTHORS
-rw-r--r-- 1 root root  17992 2011-04-15 10:31 Humanity-Dark/COPYING
-rw-r--r-- 1 root root  17992 2011-04-15 10:31 Humanity/COPYING
-rw-r--r-- 1 root root   4776 2011-03-29 08:57 Faenza/apps/16/DC++.xpm
-rw-r--r-- 1 root root   3816 2011-03-29 08:57 Faenza/apps/22/DC++.xpm
-rw-r--r-- 1 root root   4008 2011-03-29 08:57 Faenza/apps/24/DC++.xpm
-rw-r--r-- 1 root root   4456 2011-03-29 08:57 Faenza/apps/32/DC++.xpm
-rw-r--r-- 1 root root   7336 2011-03-29 08:57 Faenza/apps/48/DC++.xpm
-rw-r--r-- 1 root root    918 2011-03-29 09:03 Faenza/apps/16/Thunar.png
    
respondido por el ændrük 13.06.2011 - 19:02
26
find . -mindepth 1 -printf '%h %f\n' | sort -t ' ' -k 2,2 | uniq -f 1 --all-repeated=separate | tr ' ' '/'

Como dice el comentario, esto también encontrará carpetas. Aquí está el comando para restringirlo a los archivos:

find . -mindepth 1 -type f -printf '%p %f\n' | ...
    
respondido por el ojblass 13.06.2011 - 20:57
5

Guárdalo en un archivo llamado duplicates.py

#!/usr/bin/env python

# Syntax: duplicates.py DIRECTORY

import os, sys

top = sys.argv[1]
d = {}

for root, dirs, files in os.walk(top, topdown=False):
    for name in files:
        fn = os.path.join(root, name)
        basename, extension = os.path.splitext(name)

        basename = basename.lower() # ignore case

        if basename in d:
            print(d[basename])
            print(fn)
        else:
            d[basename] = fn

Luego haz que el archivo sea ejecutable:

chmod +x duplicates.py

Ejecutar en, por ejemplo, así:

./duplicates.py ~/images

Debería generar pares de archivos que tengan el mismo nombre de base (1). Escrito en python, deberías poder modificarlo.

    
respondido por el loevborg 13.06.2011 - 21:01
3

Supongo que solo necesita ver estos "duplicados", luego los maneja manualmente. Si es así, este código bash4 debería hacer lo que quieras, creo.

declare -A array=() dupes=()
while IFS= read -r -d '' file; do 
    base=${file##*/} base=${base%.*}
    if [[ ${array[$base]} ]]; then 
        dupes[$base]+=" $file"
    else
        array[$base]=$file
    fi
done < <(find /the/dir -type f -print0)

for key in "${!dupes[@]}"; do 
    echo "$key: ${array[$key]}${dupes[$key]}"
done

Consulte enlace y / o el manual de bash para obtener ayuda sobre la sintaxis de la matriz asociativa.

    
respondido por el geirha 13.06.2011 - 18:23
1

Este es bname:

#!/bin/bash
#
#  find for jpg/png/gif more files of same basename 
#
# echo "processing () "
bname=$(basename "" .)
find -name "$bname.jpg" -or -name "$bname.png"

Hacerlo ejecutable:

chmod a+x bname 

Invocarlo:

for ext in jpg png jpeg gif tiff; do find -name "*.$ext" -exec ./bname "{}" $ext ";"  ; done

Pro:

  • Es sencillo y sencillo, por lo tanto extensible.
  • Maneja espacios en blanco, pestañas, saltos de línea y alimentaciones de página en nombres de archivos, afaik. (Suponiendo que no existe tal cosa en el nombre de la extensión).

Con:

  • Encuentra siempre el archivo en sí, y si encuentra a.gif para a.jpg, también encontrará a.jpg for a.gif. Entonces, para 10 archivos del mismo nombre base, encuentra 100 coincidencias al final.
respondido por el user unknown 13.06.2011 - 20:15

Lea otras preguntas en las etiquetas