निर्देशिका में डुप्लिकेट फ़ाइलें कैसे निकालें?


25

मैंने एक निर्देशिका में बहुत सारी छवियां डाउनलोड कीं।
डाउनलोडर ने उन फ़ाइलों का नाम बदला जो पहले से मौजूद हैं।
मैंने कुछ फ़ाइलों को मैन्युअल रूप से नाम दिया है।

a.jpg
b.jpg
b(2).jpg
hello.jpg      <-- manually renamed `b(3).jpg`
c.jpg
c(2).jpg
world.jpg      <-- manually renamed `d.jpg`
d(2).jpg
d(3).jpg

डुप्लिकेट वालों को कैसे निकालें? परिणाम होना चाहिए:

a.jpg
b.jpg
c.jpg
world.jpg

नोट: नाम कोई मायने नहीं रखता। मुझे सिर्फ uniq फाइलें चाहिए।

जवाबों:


27

बैश 4.x

#!/bin/bash
declare -A arr
shopt -s globstar

for file in **; do
  [[ -f "$file" ]] || continue

  read cksm _ < <(md5sum "$file")
  if ((arr[$cksm]++)); then 
    echo "rm $file"
  fi
done

यह दोनों पुनरावर्ती है और किसी भी फ़ाइल नाम को संभालता है। नकारात्मक पक्ष यह है कि यह साहचर्य सरणियों और पुनरावर्ती खोज का उपयोग करने की क्षमता के लिए संस्करण 4.x की आवश्यकता है। echoयदि आपको परिणाम पसंद हैं तो निकालें ।

gawk संस्करण

gawk '
  {
    cmd="md5sum " q FILENAME q
    cmd | getline cksm
    close(cmd)
    sub(/ .*$/,"",cksm)
    if(a[cksm]++){
      cmd="echo rm " q FILENAME q
      system(cmd)
      close(cmd)
    }
    nextfile
  }' q='"' *

ध्यान दें कि यह अभी भी उन फ़ाइलों पर टूट जाएगा जिनके नाम में दोहरे-उद्धरण हैं। उस के साथ पाने के लिए कोई वास्तविक तरीका नहीं है awkechoयदि आपको परिणाम पसंद हैं तो निकालें ।


ठीक है, बैश संस्करण ने मेरे लिए काम किया, लेकिन मेरे परीक्षण में, 2 समान फ़ोल्डरों के साथ, इसने एक फ़ोल्डर में डुप्लिकेट का आधा और दूसरे में आधा हटा दिया। क्यूं कर। मैं एक फ़ोल्डर के सभी (डुप्लिकेट) को हटाने की उम्मीद करूंगा।
फेरूओ

@ फ़ेरोआ शायद वे बिल्कुल डुप्लिकेट नहीं थे। अगर सिर्फ एक बिट md5 हैश है कि मेरी स्क्रिप्ट का उपयोग कर रहा है कि नकल का निर्धारण करने के लिए पूरी तरह से अलग होगा। यदि आप प्रत्येक फ़ाइल के हैश को देखना चाहते हैं, तो आप echo cksmलाइन शुरू करने के ठीक बाद जोड़ सकते हैं read
घेराबंदी

नहीं, सभी "डुप्लिकेट" (प्रतियां) हटा दिए गए थे, शेष 1 संस्करण, चलो मूल कहते हैं। एक फ़ोल्डर से आधी प्रतियां हटा दी गईं, और दूसरे आधे दूसरे फ़ोल्डर से (प्रतियों का 100% विलोपन)। मेरी 100% अधिक मात्रा में प्रतियों के लिए है, समग्रता की नहीं
फेरो डे

@Ferroao मैं देख रहा हूँ। उस स्थिति में ऐसा लगता है जब बैश अपने पुनरावर्ती पथ विस्तार के माध्यम से करता है **, तो यह सूची को इस तरह से आदेश देता है कि दो फ़ोल्डर सभी 1 के बजाय एक दूसरे से जुड़े हुए हैं, फिर सभी फ़ोल्डर 2। स्क्रिप्ट हमेशा पहले 'मूल' को छोड़ देगी। यह हिट के रूप में यह सूची के माध्यम से iterates। यह देखने के लिए कि क्या यह सच है echo $file, आप readलाइन से पहले कर सकते हैं।
घेराबंदी

43

fdupes आपकी पसंद का उपकरण है। वर्तमान निर्देशिका में सभी डुप्लिकेट फ़ाइलें (सामग्री द्वारा, नाम से नहीं) खोजने के लिए:

fdupes -r .

मैन्युअल रूप से डुप्लिकेट फ़ाइलों को हटाने की पुष्टि करने के लिए:

fdupes -r -d .

स्वचालित रूप से सभी प्रतियों को हटाने के लिए, लेकिन प्रत्येक डुप्लिकेट फ़ाइल की पहली ( चेतावनी दी जाए, यह चेतावनी, यह वास्तव में फ़ाइलों को हटा देती है, जैसा कि अनुरोध किया गया है ):

fdupes -r -f . | grep -v '^$' | xargs rm -v

मैं हटाने से पहले मैन्युअल रूप से फ़ाइलों की जांच करने की सलाह दूंगा:

fdupes -rf . | grep -v '^$' > files
... # check files
xargs -a files rm -v

महान काम करता है, लेकिन विफल रहता है अगर फ़ाइल नामों में रिक्त स्थान होते हैं।
डैनियल वुल्फ

1
@ डैनियलवॉल्फ xargs विकल्प के साथ प्रयास करें-d '\n'
जैकब

1
इसके अलावा, fdupes के नए संस्करणों में अंतर्निहित सभी विकल्पों को हटाने के लिए विकल्प है, लेकिन डुप्लिकेट फ़ाइलों की सूची में पहला: fdupes -rdN .जहां -r पुनरावर्ती है, -d हटा रहा है और -N कोई संकेत नहीं है
रैंड

धन्यवाद, यह बकाया है क्योंकि 2 से अधिक डुप्लिकेट का पता लगा सकता है और आपको यह चयन करने की अनुमति देता है कि आप उनमें से कौन से ड्यूप्स को संरक्षित करना चाहते हैं (या उन सभी को)।
16


1

थोड़ा आलसी होने के नाते, मुझे ऑनलाइन खोजने में बहुत समय नहीं लगा ।

आपको पहले प्रत्येक फ़ाइल का सीआरसी चेकसम बनाना होगा, क्योंकि आप स्पष्ट रूप से केवल सटीक डुप्लिकेट को निकालना चाहते हैं।

cksum  *.jpg | sort -n > filelist

फिर, इस फाइल की सूची पर, फिर से चेकसम में पढ़ना और फ़ाइल नाम भी। यदि दो चेकसम समान हैं, तो फ़ाइल हटा दी जाएगी। यह काम करता है, चूंकि सॉर्ट संख्यात्मक है, और चेकसमों पर केवल सॉर्ट करता है, जो फ़ाइलों की नकल करते हैं।

old=""
while read sum lines filename
do
      if [[ "$sum" != "$old" ]] ; then
            old="$sum"
            continue
      fi
      rm -f "$filename"
done < filelist

जाहिर है, यह पुनरावर्ती रूप से काम नहीं करता है।


1

अद्वितीय सामग्री वाली फ़ाइलों का परीक्षण कैसे करें?

if diff "$file1" "$file2" > /dev/null; then
    ...

हम निर्देशिका में फ़ाइलों की सूची कैसे प्राप्त कर सकते हैं?

files="$( find ${files_dir} -type f )"

हम उस सूची से कोई भी 2 फाइलें प्राप्त कर सकते हैं और जांच सकते हैं कि क्या उनके नाम अलग हैं और सामग्री समान है।

#!/bin/bash
# removeDuplicates.sh

files_dir=$1
if [[ -z "$files_dir" ]]; then
    echo "Error: files dir is undefined"
fi

files="$( find ${files_dir} -type f )"
for file1 in $files; do
    for file2 in $files; do
        # echo "checking $file1 and $file2"
        if [[ "$file1" != "$file2" && -e "$file1" && -e "$file2" ]]; then
            if diff "$file1" "$file2" > /dev/null; then
                echo "$file1 and $file2 are duplicates"
                rm -v "$file2"
            fi
        fi
    done
done

उदाहरण के लिए, हमारे पास कुछ dir है:

$> ls .tmp -1
all(2).txt
all.txt
file
text
text(2)

इसलिए केवल 3 अनूठी फाइलें हैं।

चलिए उस स्क्रिप्ट को:

$> ./removeDuplicates.sh .tmp/
.tmp/text(2) and .tmp/text are duplicates
removed `.tmp/text'
.tmp/all.txt and .tmp/all(2).txt are duplicates
removed `.tmp/all(2).txt'

और हमें केवल 3 फाइलें ही मिली हैं।

$> ls .tmp/ -1
all.txt
file
text(2)

1

डुप्लिकेट फ़ाइलों को हटाने के लिए मैंने यह छोटी स्क्रिप्ट लिखी थी

https://gist.github.com/crodas/d16a16c2474602ad725b

मूल रूप से यह एक अस्थायी फ़ाइल का उपयोग करता है (/tmp/list.txt फाइलों और उनके हैश का एक नक्शा बनाने के लिए ) का उपयोग करता है। बाद में मैं उस फ़ाइलों और यूनिक्स पाइपों के जादू का उपयोग बाकी काम करने के लिए करता हूं।

स्क्रिप्ट कुछ भी नहीं हटाएगी, लेकिन फाइलों को हटाने के लिए कमांड प्रिंट करेगी।

mfilter.sh ./dir | bash

आशा करता हूँ की ये काम करेगा


1

डुप्लिकेट फ़ाइलों को हटाने का अधिक संक्षिप्त संस्करण (सिर्फ एक पंक्ति)

young@ubuntu-16:~/test$ md5sum `find ./ -type f` | sort -k1 | uniq -w32 -d | xargs rm -fv

find_same_size.sh

#!/usr/bin/env bash
#set -x
#This is small script can find same size of files.
find_same_size(){

if [[ -z $1 || ! -d $1 ]]
then
echo "Usage $0 directory_name" ;
 exit $?
else
dir_name=$1;
echo "current directory is $1"



for i in $(find $dir_name -type f); do
   ls -fl $i
done | awk '{f=""
        if(NF>9)for(i=9;i<=NF;i++)f=f?f" "$i:$i; else f=$9;
        if(a[$5]){ a[$5]=a[$5]"\n"f; b[$5]++;} else a[$5]=f} END{for(x     in b)print a[x] }' | xargs stat -c "%s  %n" #For just list files
 fi
   }

find_same_size $1


young@ubuntu-16:~/test$ bash find_same_size.sh tttt/ | awk '{ if($1 !~   /^([[:alpha:]])+/) print $2}' | xargs md5sum | uniq -w32 -d | xargs rm -vf


0

प्रक्रिया में निर्देशिका में प्रत्येक और हर फ़ाइल के चेकसम की गणना करके शेष और संभवतः सभी शेष उत्तर बहुत ही अयोग्य हैं।

परिमाण तेजी से दृष्टिकोण का एक संभावित आदेश पहले प्रत्येक फ़ाइल का आकार प्राप्त करना है, जो लगभग तत्काल ( lsया stat) है, और फिर गैर-अद्वितीय आकार वाली फ़ाइलों के लिए केवल चेकसम की गणना और तुलना करें।


0

यह वह नहीं है जो आप पूछ रहे हैं, लेकिन मुझे लगता है कि कोई व्यक्ति इसे उपयोगी पा सकता है जब चेकसम समान नहीं होते हैं, लेकिन नाम समान है (कोष्ठकों में प्रत्यय के साथ)। यह स्क्रिप्ट ("अंक") के रूप में प्रत्ययों वाली फ़ाइलों को हटा देती है

#! /bin/bash
# Warning: globstar excludes hidden directories.
# Turn on recursive globbing (in this script) or exit if the option is not supported:
shopt -s globstar || exit
for f in **
do
extension="${f##*.}"
#get only files with parentheses suffix
FILEWITHPAR=$( echo "${f%.*}".$extension | grep -o -P "(.*\([0-9]\)\..*)")
# print file to be possibly deleted
if [ -z "$FILEWITHPAR" ] ;then
:
else
echo "$FILEWITHPAR ident"
# identify if a similar file without suffix exists
FILENOPAR=$(echo $FILEWITHPAR | sed -e 's/^\(.*\)([0-9])\(.*\).*/\1\2/')
echo "$FILENOPAR exists?"
if [ -f "$FILENOPAR" ]; then
#delete file with suffix in parentheses
echo ""$FILEWITHPAR" to be deleted"
rm -Rf "$FILEWITHPAR"
else
echo "no"
fi
fi
done

-3

मुझे एक छोटा सा कार्यक्रम मिला जो वास्तव में इस तरह के कार्यों को सरल बनाता है: fdupes


कृपया स्थापना निर्देश और प्रश्न के लिए उपयुक्त उपयोग उदाहरण जोड़ें।
8
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.