क्या एक फ़ोल्डर से फ़ाइलों को हटाने का एक तरीका है जो किसी अन्य फ़ोल्डर में हैं?


21

मान लें कि मैं फ़ोल्डर A से फ़ाइलें कॉपी और पेस्ट करता हूं, जिसमें शामिल हैं:

फ़ोल्डर A:

file1.cfg  
file2.txt  
file3.esp  
file4.bsa  

फोल्डर B में, जिसे अपडेट करने के बाद:

फ़ोल्डर B:

apples.mp3  
file1.cfg    *
file2.txt    *
file3.esp    *
file4.bsa    *
turtles.jpg

क्या फ़ोल्डर ए से सभी फ़ाइलों को हटाने का एक तरीका है जो फ़ोल्डर बी (एक * के साथ चिह्नित) में हैं? मैन्युअल रूप से प्रत्येक को चुनने और हटाने के बाद, या कॉपी-पेस्ट के बाद ctrl-Z'ing सही

मैं या तो एक विंडोज़ विधि या कुछ सॉफ़्टवेयर पसंद करूंगा जो ऐसा कर सकता है

धन्यवाद!


4
आप कैसे जानते हैं कि वे एक ही फाइल सामग्री-वार हैं? मैं एक ऐसे परिदृश्य की कल्पना नहीं कर सकता, जहाँ आप किसी फ़ाइल को केवल फ़ाइल नाम पर आधारित डुप्लिकेट मानने के लिए आँख बंद करके विचार करना चाहेंगे।
rory.ap

@roryap मुझे लगता है कि यह प्रश्न उत्पन्न हुआ था क्योंकि ओपी ने फ़ोल्डर 1 से फ़ोल्डर 2 तक की फ़ाइलों को कॉपी किया, सभी को बदल दिया और अब सोचता है, हम्म, यह एक गलती थी, लेकिन यह एहसास होता है कि अगले दिन, इसलिए पूर्ववत करना संभव नहीं है। लेकिन आप सही हैं, आपको पता नहीं चल सकता है।
LPChip

13
बस एक गूंगा सवाल ... "कट" और "पेस्ट" का उपयोग क्यों न करें?
DaMachk

@DaMachk यदि आप नेटवर्क ड्राइव या रिमूवेबल मीडिया के साथ काम कर रहे हैं, तो कॉपी करें-> सत्यापित करें-> क्लीन-अप एक उचित मार्ग है। यदि फ़ाइलों को किसी प्रक्रिया द्वारा उपयोग किया जाता है, तो इसे कॉपी पर परीक्षण करना एक अच्छा विचार हो सकता है (मैं अपने कोड में क्लीबर्बिंग इनपुट फ़ाइल (उदाहरण के लिए) में बग के मामले में अजगर डेटा विश्लेषण के लिए फ़ाइलों के साथ ऐसा करता हूं। यह हो सकता है) जितना आवश्यक हो उतना उपयोग न करें, लेकिन पुरानी आदतें और वह सब। वैकल्पिक रूप से ओपी में कट के बजाय गलत क्लिक की गई कॉपी हो सकती है,
क्रिस एच

जवाबों:


35

वहाँ WinMerge नामक मुफ्त सॉफ्टवेयर है । आप डुप्लिकेट को मैच करने के लिए इस सॉफ़्टवेयर का उपयोग कर सकते हैं। सबसे पहले, File→ का उपयोग करें Open, और दोनों निर्देशिकाओं का चयन करें, उन फ़ाइलों के साथ फ़ोल्डर जिन्हें आप बाईं ओर रखना चाहते हैं, और जिन्हें आप दाईं ओर नहीं रखते हैं। फिर, करने के लिए जाना Viewहै, और अचयनित Show Different Items, Show Left Unique Items, और Show Right Unique Items। यह सूची में केवल समान फ़ाइलों को छोड़ देगा। उसके बाद, Edit→ चुनें Select All, किसी भी फाइल पर राइट-क्लिक करें, और Delete→ पर क्लिक करें Right। यह डुप्लिकेट फ़ोल्डर को राइट-हैंड फ़ोल्डर से हटा देगा।

WinMerge का डेमो


इस पद्धति का लाभ यह है कि यह पता लगा सकता है कि क्या फाइलें सामग्री-वार के समान नहीं हैं, यदि यह महत्वपूर्ण है। WinMerge उन सभी कारकों की तुलना कर सकता है जो किसी के लिए मायने रखते हैं।

25

यह कमांड का उपयोग करके कमांड के माध्यम से किया जा सकता है forfiles

मान लें कि आपके पास Folder A स्थित है c:\temp\Folder Aऔर Folder B अंदर स्थित हैc:\temp\Folder B

कमांड तब होगी:

c:\>forfiles /p "c:\temp\Folder A" /c "cmd /c del c:\temp\Folder B\@file"

ऐसा करने के बाद, Folder B में सभी फ़ाइलें जो Folder A. में मौजूद हैं, को हटा दिया जाएगा। ध्यान रखें कि यदि फ़ोल्डर B में समान नाम वाली फाइलें हैं, लेकिन समान सामग्री नहीं है, तो भी वे हटा दी जाएंगी।

सबफ़ोल्डर्स में फ़ोल्डर्स के साथ काम करने के लिए इसे विस्तारित करना संभव है, लेकिन इस डर से अनावश्यक जटिल बनने के लिए, मैंने इसे पोस्ट करने का फैसला किया है। इसके लिए / s और @relpath विकल्प (और आगे के परीक्षण xD) की आवश्यकता होगी


11

आप इस PowerShell स्क्रिप्ट का उपयोग कर सकते हैं:

$folderA = 'C:\Users\Ben\test\a\' # Folder to remove cross-folder duplicates from
$folderB = 'C:\Users\Ben\test\b\' # Folder to keep the last remaining copies in
Get-ChildItem $folderB | ForEach-Object {
    $pathInA = $folderA + $_.Name
    If (Test-Path $pathInA) {Remove-Item $pathInA}
}

उम्मीद है कि यह काफी आत्म-व्याख्यात्मक है। यह Folder B में प्रत्येक आइटम को देखता है, जाँचता है कि क्या Folder A में समान नाम वाला कोई आइटम है, और यदि ऐसा है, तो यह Folder A आइटम को हटा देता है। ध्यान दें कि \फ़ोल्डर पथ में अंतिम महत्वपूर्ण है।

एक-पंक्ति संस्करण:

gci 'C:\Users\Ben\test\b\' | % {del ('C:\Users\Ben\test\a\' + $_.Name) -EA 'SilentlyContinue'}

यदि आपको परवाह नहीं है कि आपको कंसोल में लाल त्रुटियों का एक जलप्रलय है, तो आप इसे हटा सकते हैं -EA 'SilentlyContinue'

इसे एक .ps1फ़ाइल के रूप में सहेजें , जैसे dedupe.ps1। इससे पहले कि आप PowerShell स्क्रिप्ट चला सकें, आपको उनका निष्पादन सक्षम करना होगा:

Set-ExecutionPolicy Unrestricted -Scope CurrentUser

तब आप इसे .\dedupe.ps1उस फ़ोल्डर में शामिल करने में सक्षम होंगे, जब आप उस फ़ोल्डर में होंगे।


4

rsync

rsyncएक प्रोग्राम है जिसका उपयोग डायरेक्टरी को सिंक्रोनाइज़ करने के लिए किया जाता है। कई (वास्तव में कई) विकल्पों में से आपके पास स्वयं को समझाने वाले --ignore-non-existing, --remove-source-filesऔर हैं --recursive

तुम कर सकते हो

rsync -avr --ignore-non-existing --recursive --remove-source-files   B/ A -v

अगर हम मान लें कि आपके पास निर्देशिका ए (4) और बी (4 + 2) में फाइलें हैं।

A       B
├── a   ├── a
├── b   ├── b
├── c   ├── c
└── d   ├── d
        ├── e
        └── f     # Before


A       B
├── a   ├── e
├── b   └── f
├── c   
└── d             # After

4

LPChip का जवाब बेहतर है।

लेकिन क्योंकि मैंने पायथन सीखना शुरू कर दिया है, मैंने सोचा, "बिल्ली, इस प्रश्न के उत्तर के रूप में पायथन स्क्रिप्ट क्यों नहीं लिखी?"

पायथन और Send2Trash स्थापित करें

कमांड लाइन से स्क्रिप्ट चलाने से पहले आपको पायथन को स्थापित करना होगा।

फिर Send2Trash स्थापित करें ताकि नष्ट की गई फाइलें बहुत कम नहीं हुई हैं लेकिन OS के ट्रैश में समाप्त हो गई हैं:

pip install Send2Trash

स्क्रिप्ट बनाएं

उदाहरण के लिए नाम के साथ एक नई फ़ाइल बनाएँ DeleteDuplicateInFolderA.py

फ़ाइल में निम्न स्क्रिप्ट की प्रतिलिपि बनाएँ।

#!/usr/bin/python

import sys
import os
from send2trash import send2trash


class DeleteDuplicateInFolderA(object):
    """Given two paths A and B, the application determines which files are in
       path A which are also in path B and then deletes the duplicates from
       path A.

       If the "dry run" flag is set to 'true', files are deleted. Otherwise
       they are only displayed but not deleted.
    """

    def __init__(self, path_A, path_B, is_dry_run=True):
        self._path_A = path_A
        self._path_B = path_B
        self._is_dry_run = is_dry_run

    def get_filenames_in_folder(self, folder_path):
        only_files = []
        for (dirpath, dirnames, filenames) in os.walk(folder_path):
            only_files.extend(filenames)
        return only_files

    def print_files(sel, heading, files):
        print(heading)
        if len(files) == 0:
            print("   none")
        else:
            for file in files:
                print("   {}".format(file))

    def delete_duplicates_in_folder_A(self):
        only_files_A = self.get_filenames_in_folder(self._path_A)
        only_files_B = self.get_filenames_in_folder(self._path_B)

        files_of_A_that_are_in_B = [file for file in only_files_A if file in only_files_B]

        self.print_files("Files in {}".format(self._path_A), only_files_A)
        self.print_files("Files in {}".format(self._path_B), only_files_B)

        if self._is_dry_run:
            self.print_files("These files would be deleted: ", [os.path.join(self._path_A, file) for file in files_of_A_that_are_in_B])
        else:
            print("Deleting files:")
            for filepath in [os.path.join(self._path_A, file) for file in files_of_A_that_are_in_B]:
                print("   {}".format(filepath))
                # os.remove(filepath)  # Use this line instead of the next if Send2Trash is not installed
                send2trash(filepath)

if __name__ == "__main__":
    if len(sys.argv) == 4:
        is_dry_run_argument = sys.argv[3]
        if not is_dry_run_argument == "--dryrun":
            println("The 3rd argument must be '--dryrun' or nothing.")
        else:
            app = DeleteDuplicateInFolderA(sys.argv[1], sys.argv[2], is_dry_run=True)
    else:
        app = DeleteDuplicateInFolderA(sys.argv[1], sys.argv[2], is_dry_run=False)
    app.delete_duplicates_in_folder_A()

प्रयोग

ड्राई रन मोड, जो आपको दिखाता है कि वास्तव में किसी भी फाइल को डिलीट किए बिना कौन सी फाइल्स डिलीट होंगी:

c:\temp> python .\DeleteDuplicateInFolderA.py c:\temp\test\A c:\temp\test\B --dryrun

फ़ाइल हटाने का तरीका, जो वास्तव में फ़ाइलों को हटाता है, इसलिए सावधान रहें:

c:\temp> python .\DeleteDuplicateInFolderA.py c:\temp\test\A c:\temp\test\B

ड्राई रन मोड का आउटपुट

Files in C:\temp\A
  1.txt
  2.txt
Files in C:\temp\B
  2.txt
  3.txt
These files would be deleted:
  C:\temp\A\2.txt

फ़ाइल हटाने मोड का आउटपुट

Files in C:\temp\A
  1.txt
  2.txt
Files in C:\temp\B
  2.txt
  3.txt
Deleting files:
  C:\temp\A\2.txt

अध्याय परीक्षा

यदि आप ऊपर दिए गए आवेदन का परीक्षण करना चाहते हैं, तो नाम की एक फाइल बनाएं DeleteDuplicateInFolderATest.pyऔर इन unittests को इसमें चिपकाएँ:

import unittest
import os
import shutil
from DeleteDuplicateInFolderA import DeleteDuplicateInFolderA


class DeleteDuplicateInFolderATest(unittest.TestCase):

    def __init__(self, *args, **kwargs):
        super(DeleteDuplicateInFolderATest, self).__init__(*args, **kwargs)
        self._base_directory = r"c:\temp\test"
        self._path_A = self._base_directory + r"\A"
        self._path_B = self._base_directory + r"\B"

    def create_folder_and_create_some_files(self, path, filename_list):
        if os.path.exists(path):
            shutil.rmtree(path)
        os.makedirs(path)
        for filename in filename_list:
            open(os.path.join(path, filename), "w+").close()

    def setUp(self):
        # Create folders and files for testing
        self.create_folder_and_create_some_files(self._path_A, ["1.txt", "2.txt"])
        self.create_folder_and_create_some_files(self._path_B, ["2.txt", "3.txt"])

    def tearDown(self):
        for path in [self._path_A, self._path_B, self._base_directory]:
            if os.path.exists(path):
                shutil.rmtree(path)

    def test_duplicate_file_gets_deleted(self):
        # Arrange
        app = DeleteDuplicateInFolderA(self._path_A, self._path_B, is_dry_run=False)

        # Act
        app.delete_duplicates_in_folder_A()

        # Assert
        self.assertFalse(os.path.isfile(self._path_A + r"\2.txt"), "File 2.txt has not been deleted.")

    def test_duplicate_file_gets_not_deleted_in_mode_dryrun(self):
        # Arrange
        app = DeleteDuplicateInFolderA(self._path_A, self._path_B, is_dry_run=True)

        # Act
        app.delete_duplicates_in_folder_A()

        # Assert
        self.assertTrue(os.path.isfile(self._path_A + r"\2.txt"), "File 2.txt should not have been deleted in mode '--dryrun'")

def main():
    unittest.main()

if __name__ == '__main__':
    main()

क्या आप मुझे बता सकते हैं कि यह लिपि "बदसूरत नरक" क्यों है? मैं अभी इसके माध्यम से पढ़ता हूं और आप जो कर रहे हैं, वह स्पष्ट है। मैं लगभग इसे CodeReview पर पेस्ट करने के लिए लुभा रहा हूं। इसके बारे में पसंद न करने के बारे में जानने के लिए।
user1717828

जाँच करने के लिए एक md5sum जोड़ना कि क्या फाइल की सामग्री समान है, एक अच्छा विकल्प होगा। इसके अलावा हटाने के बजाय ओएस कचरा तंत्र का उपयोग करना।
लोलस्क

@ user1717828: मैंने कोड का पुनर्गठन किया है, उस टिप्पणी को हटा दिया है और CodeReview.SE पर कोड पोस्ट करने के लिए आपका सुझाव ले लिया है ।
लर्नकुरेव

@ लोकेस्क: Send2Trash हिस्सा: किया गया। विचार के लिए आपका धन्यवाद!
लर्नकुरेव

1
@barlop, मैं मूल पोस्ट का जवाब दे रहा था, टिप्पणी नहीं।
user1717828

1

बैश का उपयोग करना

for f in $(ls /path/to/folderB/); do 
    rm -rf /path/to/folderA/$f
done

सुनिश्चित करें कि फ़ाइल होने पर जाँच करके या फ़ाइल नाम सुरक्षित होने पर आप अधिक सुरक्षित हो सकते हैं। लेकिन यह मानते हुए कि आप इसे पूरा करना चाहते हैं, और इसमें किसी भी हास्यास्पद नाम की फाइल नहीं है folderB- यह एक त्वरित और गंदा तरीका है। (और यदि आप Win10 + बैश नहीं चला रहे हैं, तो git के साथ आने वाले bash एमुलेटर का उपयोग कर सकते हैं )


हो सकता है कि आपको निर्देशिकाओं को खोजने पर एक चेक जोड़ने की आवश्यकता हो ...
Hastur

1

कुल कमांडर की तरह किसी भी NC- शैली कार्यक्रम में एक निर्देशिका अंतर कमांड है जो दोनों टैब में फ़ाइलों का चयन करता है जो अन्य टैब से अलग हैं। इस कमांड tabको बड़ी डायरेक्टरी (B) में कॉल करें, चयन को इनवर्ट करें *और डिलीट करें। इससे उन फाइलों को न हटाने का फायदा होता है, जो शायद (किसी तरह) बदल चुकी होती हैं और वे उसी तरह की नहीं होती हैं जिस नाम से वे सहमत होते हैं। आप हटाने के बाद इन्हें ढूंढने के लिए समान निर्देशिका भिन्न कमांड का उपयोग कर सकते हैं।

मुझे लगता है कि मैं नब्बे के दशक में फंस गया हूं ... लेकिन मैंने वास्तव में कुछ भी अधिक सुरुचिपूर्ण नहीं देखा है :-) अब तक यह एकमात्र ऐसा उत्तर है जिसकी आवश्यकता कुछ 5 कीस्ट्रोक्स और कोई स्क्रिप्टिंग / कमांड लाइन नहीं है।


1

मान लीजिए कि मैं फ़ोल्डर A से फ़ोल्डर B में फ़ाइलों को कॉपी और पेस्ट करता हूं।

क्या फ़ोल्डर A से सभी फ़ाइलों को हटाने का एक तरीका है जो फ़ोल्डर B में हैं? मैन्युअल रूप से प्रत्येक को चुनने और हटाने के बाद, या कॉपी-पेस्ट के बाद ctrl-Z'ing सही

विंडोज विधि

यदि आपको हमेशा एक स्थान से दूसरे स्थान पर फ़ाइलों को कॉपी करने की आवश्यकता होती है और फिर बाद में सुनिश्चित करें कि जिन फ़ाइलों की प्रतिलिपि सफलतापूर्वक बनाई गई थी, उन्हें मूल स्रोत स्थान से भी हटा दिया गया है, तो नीचे एक बैच स्क्रिप्ट समाधान है जिसे आप केवल एक कार्य के साथ उस संपूर्ण कार्य को स्वचालित करने के लिए उपयोग कर सकते हैं प्रत्येक रन पर साधारण क्लिक करें।

  • अपनी आवश्यकताओं के अनुसार SourceDirऔर DestDirचर निर्धारित करना सुनिश्चित करें ।

  • इसके अतिरिक्त, नीचे दी गई स्क्रिप्ट के भाग में ("%SourceDir%\*.*") DOआप *.*फ़ाइल नाम ( File A.txt) या फ़ाइल एक्सटेंशन ( *.wav) के लिए आवश्यकतानुसार अधिक स्पष्ट होने के लिए मान बदल सकते हैं ।


@ECHO ON
SET SourceDir=C:\Users\User\Desktop\Source
SET DestDir=C:\Users\User\Desktop\Dest

FOR %%A IN ("%SourceDir%\*.*") DO XCOPY /F /Y "%%~A" "%DestDir%\" && DEL /Q /F "%%~A"
GOTO EOF

आगे के संसाधन

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