फ़ोल्डर पदानुक्रम के भीतर डुप्लिकेट फ़ाइल नामों की खोज करें?


29

मेरे पास एक फ़ोल्डर है img, इस फ़ोल्डर में उप-फ़ोल्डर्स के कई स्तर हैं, जिनमें से सभी में छवियां हैं। मैं उन्हें एक छवि सर्वर में आयात करने जा रहा हूं।

आम तौर पर छवियों (या किसी भी फाइल) का एक ही नाम हो सकता है जब तक वे एक अलग निर्देशिका पथ में होते हैं या एक अलग एक्सटेंशन होते हैं। हालाँकि, जो छवि सर्वर मैं उन्हें आयात कर रहा हूं, उसके लिए सभी छवि नामों को अद्वितीय होने की आवश्यकता है (भले ही एक्सटेंशन अलग हों)।

उदाहरण के लिए छवियों background.pngऔर background.gifक्योंकि भले ही वे एक्सटेंशन अलग होता है वे अभी भी एक ही फाइल नाम अनुमति नहीं दी जाएगी। भले ही वे अलग-अलग उप-फ़ोल्डर्स में हों, फिर भी उन्हें अद्वितीय होना चाहिए।

इसलिए मैं सोच रहा हूं कि क्या मैं imgफ़ाइलों की एक सूची खोजने के लिए फ़ोल्डर में एक पुनरावर्ती खोज कर सकता हूं , जिसमें समान नाम (एक्सटेंशन को छोड़कर) है।

क्या कोई ऐसा आदेश है जो यह कर सकता है?


@DavidFoerster तुम सही हो! मुझे नहीं पता कि मैंने क्यों सोचा था कि यह डुप्लिकेट फ़ाइलों को खोजने (और हटाने) के लिए एक डुप्लिकेट हो सकता है , लेकिन स्पष्ट रूप से यह नहीं है।
एलियाह कगन

जवाबों:


17

FSlint Fslint स्थापित करें एक बहुमुखी डुप्लिकेट खोजक है जिसमें डुप्लिकेट नाम खोजने के लिए एक फ़ंक्शन शामिल है:

FSlint

उबंटू के लिए एफएसलिंट पैकेज ग्राफिकल इंटरफेस पर जोर देता है, लेकिन जैसा कि एफएसलिंट एफएक्यू में बताया गया है एक कमांड-लाइन इंटरफेस कार्यक्रमों के माध्यम से उपलब्ध है /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

धन्यवाद यह काम किया। कुछ परिणाम बैंगनी और कुछ हरे रंग में हैं। क्या आप जानते हैं कि अलग-अलग रंगों का क्या मतलब होता है?
जद इसाक्स

@ जॉन ऐसा लगता है कि FSlint ls -lअपने आउटपुट को प्रारूपित करने के लिए उपयोग कर रहा है । इस प्रश्न को यह स्पष्ट करना चाहिए कि रंगों का क्या अर्थ है।
æंड्रिड्स

FSlint पर बहुत अधिक निर्भरताएँ हैं।
नवीं

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नहीं है क्योंकि यह एक अलग क्षेत्र परिसीमन का चयन करने की सुविधा प्रदान नहीं करता है।
डेविड फ़ॉस्टर

@DavidFoerster, आपका Rev 6 एक सुधार था, लेकिन आपकी टिप्पणी के बारे में, कब से sedअप्रचलित है? रहस्यमय? ज़रूर। अप्रचलित? यह नही है कि मैं जानता हूँ। (और मैं सिर्फ जाँच करने के लिए खोजा गया था।)
cp.engr

@ cp.engr: sed अप्रचलित नहीं है। यह मेरा एक और बदलाव के बाद आह्वान अप्रचलित हो गया।
डेविड फ़ॉस्टर

@DavidFoerster, अप्रचलित मुझे सही शब्द की तरह प्रतीत नहीं होता है, फिर। मुझे लगता है कि "कम" एक बेहतर फिट होगा। भले ही, स्पष्ट करने के लिए धन्यवाद।
cp.engr

@ cp.engr: सुझाव के लिए धन्यवाद! मुझे वह शब्द नहीं पता था, लेकिन यह स्थिति को बेहतर ढंग से फिट करने के लिए प्रतीत होता है।
डेविड फ़ॉस्टर

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

यह उन फ़ाइलों के आउटपुट का उत्पादन करना चाहिए जिनके पास एक ही बेसनेम (1) है। अजगर में लिखा गया है, आपको इसे संशोधित करने में सक्षम होना चाहिए।


यह ठीक से काम नहीं करता है। यह पता लगाता है P001.ORFऔर P001 (1).ORFडुप्लिकेट के रूप में और यह भी लगता है कि मेरी फ़ाइलों का 60% डुप्लिकेट हैं जो कि गलत है मुझे पूरा यकीन है। fslintडुप्लिकेट फ़ाइल नाम की एक वास्तविक संख्या मिली जो 3% के करीब है।
रॉल्फ

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 और / या सहयोगी सरणी सिंटैक्स पर मदद के लिए बैश मैनुअल देखें ।


मैं टर्मिनल में उस तरह की कमांड कैसे निष्पादित कर सकता हूं? क्या यह कुछ ऐसा है जिसे मुझे पहले किसी फ़ाइल को सहेजने और फ़ाइल को निष्पादित करने की आवश्यकता है?
जद इसाक्स

@ जॉन आइज़ैक आप इसे टर्मिनल में कॉपी / पेस्ट कर सकते हैं या आप इसे एक फ़ाइल में रख सकते हैं और इसे एक स्क्रिप्ट के रूप में चला सकते हैं। या तो मामला उसी को हासिल करेगा।
जियरा

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

समर्थक:

  • यह सीधा और सरल है, इसलिए एक्स्टेंसिबल है।
  • फ़ाइल नाम, afaik में रिक्तियां, टैब, लाइनब्रेक और पेजफीड संभालता है। (विस्तार-नाम में ऐसी कोई बात नहीं मानकर)।

कोन:

  • यह हमेशा फ़ाइल को ही ढूँढता है, और यदि यह a.jpg के लिए a.gif पाता है, तो यह a.gpg के लिए a.jpg भी पाएगा। तो एक ही बेसनेम की 10 फाइलों के लिए, यह अंत में 100 मैचों का पता लगाता है।

0

मेरी जरूरतों के लिए, लोवबोर्ग की स्क्रिप्ट में सुधार (स्कैन करते समय समूहीकृत आउटपुट, ब्लैकलिस्ट, क्लीनर आउटपुट शामिल है)। मैं 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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.