폴더 계층 내에서 중복 파일 이름을 검색 하시겠습니까?


29

나는라는 폴더가 img모두 이미지를 포함,이 폴더 하위 폴더의 많은 수준을 보유하고 있습니다. 이미지 서버로 가져옵니다.

일반적으로 이미지 (또는 파일)는 다른 디렉토리 경로에 있거나 확장자가 다른 한 이름이 동일 할 수 있습니다. 그러나 이미지를 가져 오는 이미지 서버는 모든 이미지 이름이 고유해야합니다 (확장명이 다르더라도).

예를 들어 이미지 background.png와는 background.gif서로 다른 확장에도 불구하고 그들은 여전히 같은 파일 이름을 가지고 있기 때문에 허용되지 않습니다. 별도의 하위 폴더에 있더라도 여전히 고유해야합니다.

따라서 img폴더 에서 재귀 검색을 수행 하여 동일한 이름 (확장자 제외)의 파일 목록을 찾을 수 있는지 궁금합니다 .

이를 수행 할 수있는 명령이 있습니까?


@DavidFoerster 당신이 맞아요! 왜 이것이 중복 파일을 찾고 삭제하는 방법 의 복제본이라고 생각했는지 모르겠지만 분명히 그렇지 않습니다.
Eliah Kagan

답변:


17

FSlint fslint 설치 는 중복 이름을 찾기위한 기능을 포함하는 다목적 복제 파인더입니다.

FSlint

Ubuntu 용 FSlint 패키지는 그래픽 인터페이스를 강조하지만 FSlint FAQ에 설명 된대로 의 프로그램을 통해 명령 줄 인터페이스를 사용할 수 있습니다 /usr/share/fslint/fslint/. 다음 --help과 같은 문서 옵션을 사용하십시오 .

$ /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.

사용법 예 :

$ /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

고마워요. 일부 결과는 자주색이며 일부는 녹색입니다. 다른 색상의 의미를 아십니까?
JD Isaacks

@John FSlint가 ls -l출력 형식을 지정하는 데 사용 하는 것 같습니다 . 이 질문 은 색상의 의미를 설명해야합니다.
ændrük

FSlint는 많은 의존성을 가지고 있습니다.
Navin

31
find . -mindepth 1 -printf '%h %f\n' | sort -t ' ' -k 2,2 | uniq -f 1 --all-repeated=separate | tr ' ' '/'

주석에서 알 수 있듯이 폴더도 찾을 수 있습니다. 파일로 제한하는 명령은 다음과 같습니다.

find . -mindepth 1 -type f -printf '%p %f\n' | sort -t ' ' -k 2,2 | uniq -f 1 --all-repeated=separate | cut -d' ' -f1

모든 복제본의 전체 (상대) 경로를 반환하도록 솔루션을 변경했습니다. 불행히도 uniq다른 필드 구분 기호를 선택하는 기능을 제공하지 않기 때문에 경로 이름에 공백이 포함되어 있지 않다고 가정합니다 .
David Foerster 17

@DavidFoerster, 귀하의 개정 6은 개선되었지만 귀하의 의견과 관련하여 언제 sed폐기 되었습니까? 비전? 확실한. 더 이상 사용되지 않습니까? 내가 아는 것은 아닙니다. (그리고 방금 확인하려고 검색했습니다.)
cp.engr

@ cp.engr : sed는 더 이상 사용되지 않습니다. 그것은 나의 또 다른 변화 이후에 불필요하게되었다.
David Foerster

@DavidFoerster, 쓸모없는 것은 나에게 맞는 단어처럼 보이지 않습니다. 나는 "명백한"것이 더 적합하다고 생각합니다. 어쨌든 명확하게 해주셔서 감사합니다.
cp.engr

@ cp.engr : 제안 해 주셔서 감사합니다! 나는 그 단어를 몰랐지만 상황에 더 잘 맞는 것 같습니다.
David Foerster

8

이것을 파일 이름으로 저장하십시오 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

그런 다음 파일을 실행 가능하게 만드십시오.

chmod +x duplicates.py

예를 들어 다음과 같이 실행하십시오.

./duplicates.py ~/images

동일한 basename (1)을 가진 파일 쌍을 출력해야합니다. 파이썬으로 작성하면 수정할 수 있어야합니다.


제대로 작동하지 않는 것 같습니다. 그것은 감지 P001.ORF하고 P001 (1).ORF중복으로 내 파일의 60 %가 잘못되었다고 생각하는 것 같습니다. 잘 모르겠습니다. fslint3 %에 가까운 실제 중복 파일 이름을 찾았습니다.
Rolf

3

이 "중복"만보고 수동으로 처리해야한다고 가정합니다. 그렇다면이 bash4 코드는 내가 원하는 것을해야합니다.

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

연관 배열 구문에 대한 도움말 은 http://mywiki.wooledge.org/BashGuide/Arrays#Associative_Arrays 및 / 또는 bash 매뉴얼을 참조 하십시오 .


터미널에서 이와 같은 명령을 어떻게 실행합니까? 먼저 파일에 저장하고 파일을 실행해야합니까?
JD Isaacks 2016 년

@John Isaacks 터미널에 복사 / 붙여 넣기하거나 파일에 넣고 스크립트로 실행할 수 있습니다. 두 경우 모두 동일하게 달성됩니다.
geirha

1

이것은 bname입니다.

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

실행 가능하게 만드십시오.

chmod a+x bname 

호출하십시오 :

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

찬성:

  • 간단하고 간단하므로 확장 가능합니다.
  • 파일 이름에서 공백, 탭, 줄 바꿈 및 페이지 피드를 처리합니다. (extension-name에 그런 것이 없다고 가정).

범죄자:

  • 항상 파일 자체를 찾고 a.jpg의 경우 a.gif를 찾으면 a.gif의 경우 a.jpg도 찾습니다. 따라서 동일한 기본 이름을 가진 10 개의 파일에 대해 결국 100 개의 일치 항목을 찾습니다.

0

내 필요에 따라 loevborg의 스크립트 개선 (그룹화 된 출력, 블랙리스트, 스캔하는 동안 더 깨끗한 출력 포함). 10TB 드라이브를 스캔하고 있었으므로 약간 더 깨끗한 출력이 필요했습니다.

용법:

python duplicates.py DIRNAME

duplicates.py

    #!/usr/bin/env python

    # Syntax: duplicates.py DIRECTORY

    import os
    import sys

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

    file_count = 0

    BLACKLIST = [".DS_Store", ]

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

            # Enable this if you want to ignore case.
            # basename = basename.lower()

            if basename not in BLACKLIST:
                sys.stdout.write(
                    "Scanning... %s files scanned.  Currently looking at ...%s/\r" %
                    (file_count, root[-50:])
                )

                if basename in d:
                    d[basename].append(fn)
                else:
                    d[basename] = [fn, ]

    print("\nDone scanning. Here are the duplicates found: ")

    for k, v in d.items():
        if len(v) > 1:
            print("%s (%s):" % (k, len(v)))
            for f in v:
                print (f)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.