कुछ फोल्डर में ग्रुप फाइल


12

मैं इस तरह के रूप में विभिन्न एक्सटेंशन वाली कुछ फ़ाइलें *.pdf, *.mp3, *.jpgकुछ अन्य लोगों और। उन सभी को एक parentनिर्देशिका में संग्रहीत किया जाता है ।

मैं सभी एक्सटेंशन की सूची कैसे प्राप्त कर सकता हूं, इन एक्सटेंशन के आधार पर कुछ फ़ोल्डर्स बना सकता हूं और फिर सभी फाइलों को अपने संबंधित फ़ोल्डरों में स्थानांतरित कर सकता हूं?

जवाबों:


13

नीचे दी गई पाइथन स्क्रिप्ट काम करती है। छिपी हुई फ़ाइलों को एक फ़ोल्डर में अलग से संग्रहीत किया जाता है, साथ ही बिना एक्सटेंशन के फाइलें भी।

चूंकि इसका उपयोग व्यापक उद्देश्यों के लिए किया जा सकता है, इसलिए मैंने कुछ विकल्प जोड़े:

  • आप ऐसे एक्सटेंशन सेट कर सकते हैं जिन्हें आप "पुनर्गठन" से बाहर करना चाहते हैं। यदि आप बस सभी को स्थानांतरित करना चाहते हैं, तो सेट करेंexclude = ()
  • आप चुन सकते हैं कि खाली फ़ोल्डर ( remove_emptyfolders = Trueया False) के साथ क्या करना है
  • यदि आप उन्हें स्थानांतरित करने के बजाय फ़ाइलों को कॉपी करना चाहते हैं, तो लाइन को प्रतिस्थापित करें:
shutil.move(subject, new_dir+"/"+name)

द्वारा:

shutil.copy(subject, new_dir+"/"+name) 

लिपी:

#!/usr/bin/env python3

import os
import subprocess
import shutil

# --------------------------------------------------------
reorg_dir = "/path/to/directory_to_reorganize"
exclude = (".jpg") # for example
remove_emptyfolders = True
# ---------------------------------------------------------

for root, dirs, files in os.walk(reorg_dir):
    for name in files:
        subject = root+"/"+name
        if name.startswith("."):
            extension = ".hidden_files"
        elif not "." in name:
            extension = ".without_extension"
        else:
            extension = name[name.rfind("."):]
        if not extension in exclude:
            new_dir = reorg_dir+"/"+extension[1:]
            if not os.path.exists(new_dir):
                os.mkdir(new_dir)
            shutil.move(subject, new_dir+"/"+name)

def cleanup():
    filelist = []
    for root, dirs, files in os.walk(reorg_dir):
        for name in files:
            filelist.append(root+"/"+name)
    directories = [item[0] for item in os.walk(reorg_dir)]
    for dr in directories:
        matches = [item for item in filelist if dr in item]
        if len(matches) == 0:
            try:
                shutil.rmtree(dr)
            except FileNotFoundError:
                pass

if remove_emptyfolders == True:
    cleanup()

यदि अवांछित डुप्लिकेट फ़ाइलों की ओवरराइटिंग का जोखिम है

कुछ अतिरिक्त लाइनों की कीमत पर, हम संभावित डुप्लिकेट को अधिलेखित करने से रोक सकते हैं। नीचे दिए गए कोड के साथ, डुप्लिकेट का नाम बदल दिया जाएगा:

duplicate_1_filename, duplicate_2_filename 

आदि।

लिपी:

#!/usr/bin/env python3

import os
import subprocess
import shutil

# --------------------------------------------------------
reorg_dir = "/path/to/directory_to_reorganize"
exclude = (".jpg") # for example
remove_emptyfolders = True
# ---------------------------------------------------------

for root, dirs, files in os.walk(reorg_dir):
    for name in files:
        subject = root+"/"+name
        if name.startswith("."):
            extension = ".hidden_files"
        elif not "." in name:
            extension = ".without_extension"
        else:
            extension = name[name.rfind("."):]
        if not extension in exclude:
            new_dir = reorg_dir+"/"+extension[1:]
            if not os.path.exists(new_dir):
                os.mkdir(new_dir)
            n = 1; name_orig = name
            while os.path.exists(new_dir+"/"+name):
                name = "duplicate_"+str(n)+"_"+name_orig
                n = n+1
            newfile = new_dir+"/"+name
            shutil.move(subject, newfile)

def cleanup():
    filelist = []
    for root, dirs, files in os.walk(reorg_dir):
        for name in files:
            filelist.append(root+"/"+name)
    directories = [item[0] for item in os.walk(reorg_dir)]
    for dr in directories:
        matches = [item for item in filelist if dr in item]
        if len(matches) == 0:
            try:
                shutil.rmtree(dr)
            except FileNotFoundError:
                pass

if remove_emptyfolders == True:
    cleanup()

संपादित करें

ओपी को ध्यान में रखते हुए, हम सभी उपयोग करने के तरीके पर एक निर्देश जोड़ना भूल गए। चूंकि डुप्लिकेट प्रश्न दिखाई देते हैं ( और कर सकते हैं ), फिर भी यह उपयोगी हो सकता है।

कैसे इस्तेमाल करे

  1. किसी एक स्क्रिप्ट को एक खाली फ़ाइल में कॉपी करें, इसे इस रूप में सहेजें reorganize.py
  2. स्क्रिप्ट के मुख्य भाग में, लक्षित निर्देशिका (फ़ाइलों को पुनर्गठित करने के लिए) के साथ सेट करें:

    reorg_dir = "/path/to/directory_to_reorganize" 

    (यदि निर्देशिका में स्थान है तो उद्धरणों का उपयोग करें)

    संभव एक्सटेंशन जिन्हें आप बाहर करना चाहते हैं (शायद नीचे की तरह कोई नहीं):

    exclude = ()

    और यदि आप बाद में खाली फ़ोल्डर निकालना चाहते हैं:

    remove_emptyfolders = True
  3. कमांड के साथ स्क्रिप्ट चलाएँ:

    python3 /path/to/reorganize.py

NB यदि आप फ़ाइलों को स्थानांतरित करने के बजाय कॉपी करना चाहते हैं , तो प्रतिस्थापित करें:

shutil.move(subject, new_dir+"/"+name)

द्वारा:

shutil.copy(subject, new_dir+"/"+name)

कृपया पहले एक छोटे नमूने पर प्रयास करें।


12

आप findकुछ जटिल execकमांड के साथ उपयोग कर सकते हैं :

find . -iname '*?.?*' -type f -exec bash -c 'EXT="${0##*.}"; mkdir -p "$PWD/${EXT}_dir"; cp --target-directory="$PWD/${EXT}_dir" "$0"' {} \;

# '*?.?*' requires at least one character before and after the '.', 
# so that files like .bashrc and blah. are avoided.
# EXT="${0##*.}" - get the extension
# mkdir -p $PWD/${EXT}_dir - make the folder, ignore if it exists

एक सूखी चलाने के लिए के cpसाथ बदलें echo


bashएक स्क्रिप्ट में कमांड को बचाने के लिए अधिक कुशल और टिडियर होगा (कहना, पर /path/to/the/script.sh):

#! /bin/bash

for i
do
    EXT="${i##*.}" 
    mkdir -p "$PWD/${EXT}_dir"
    mv --target-directory="$PWD/${EXT}_dir" "$i" 
done

और फिर चलाएं find:

find . -iname '*?.?*' -type f -exec /path/to/the/script.sh {} +

यह दृष्टिकोण बहुत लचीला है। उदाहरण के लिए, एक्सटेंशन ( filename.ext) के बजाय फ़ाइल नाम का उपयोग करने के लिए , हम इसके लिए इसका उपयोग करेंगे EXT:

NAME="${i##*/}"
EXT="${NAME%.*}"

+1; -iname '*.*'कोने मामलों के बारे में मैं ... अच्छा विचार चिंतित था का ध्यान रखना चाहिए!
रमनो

@ रमनो *.fig.bakया नहीं .profile/.bashrc, लेकिन इसे केवल एक्सटेंशन वाली फ़ाइलों को संभालना चाहिए, कम से कम। धन्यवाद।
मुरु

6
ls | gawk -F. 'NF>1 {f= $NF "-DIR"; system("mkdir -p " f ";mv " $0 " " f)}'

विस्तार की सूची की गणना (आगे बढ़ने के बाद):

ls -d *-DIR

विस्तार की सूची की गणना (आगे बढ़ने से पहले):

ls -X | grep -Po '(?<=\.)(\w+)$'| uniq -c | sort -n

(इस अंतिम छूट में, हम प्रत्येक एक्सटेंशन के लिए फाइलों की संख्या की गणना कर रहे हैं और इसे छांट रहे हैं)


1
क्षमा करें: एक टाइपो "mkdir -f" को "mkdir -p" के लिए सही किया गया था (यदि पहले से ही मौजूद है तो इसे अनदेखा करें)

क्या uniq को छाँटने के बाद लागू नहीं किया जाता है? और कृपया ls के आउटपुट को पार्स न करें।
मुरु

@ muru, (भाग 1) ls -X गारंटी देता है कि एक्सटेंशन क्रमबद्ध हैं। अंतिम सॉर्ट सिर्फ एक्सटेंशन तालिका को घटनाओं की संख्या के आधार पर क्रमबद्ध करना था - प्रासंगिकता। (मैं सही हूँ?)।

@ मेरी, (भाग 2) ls -X | grep -Po '(?<=\.)(\w+)$'मेरा पहला विचार था एक्सटेंशन की क्रमबद्ध सूची प्राप्त करना। क्या यह बहुत बुरा है? आपकी क्या सलाह है?

मैं भूल गया कि क्या ls -Xकरता है। जैसा कि मैं इसके खिलाफ क्यों सुझाता हूंls , unix.stackexchange.com/q/128985/70524 और unix.stackexchange.com/q/112125/70524 देखें । आप जो करते हैं, उसे प्राप्त करने के लिए, मैं एक लंबा रास्ता तय करूंगा: find . -type f -name '*?.?*' -print0 | sed -z 's/.*\.//' | sort -zu(एक वैकल्पिक के साथ | uniq -cz, अगर मायने रखता है)। और find ... -print0 | gawk -v RS='\0'(भले ही वह बहुत पोर्टेबल न हो ) पहले के लिए।
मूरू

5

इस शेल स्क्रिप्ट को आज़माएं।

#!/bin/sh
src=`dirname "$1"`/`basename "$1"`;
for file in "$src"/*?.?*; do
  if test -f "$file"; then
    dest="$src${file##*.}"_files;
    mkdir -p "$dest";
    mv "$file" "$dest";
  fi;
done;

# pass the directory to re-organize as first argument
# moves only regular files which have extension
# ignores other type of files including
# files having no extension, hidden files, directories, and links.

1
मुझे खेद है, यह एक त्रुटि है। मैं की प्रत्येक पुनरावृत्ति प्रतिस्थापित करने के लिए होना चाहिए filepathके साथ file। मैं इसे सीधे ठीक करूँगा।
प्रशांत कर्मकार

कृपया ls के आउटपुट को पार्स न करें। इसके बजाय, करोfor file in "$src"/*?.?*; do ..
मूरू

@ अगर किसी फ़ाइल के नाम में रिक्त स्थान है तो वह सही तरीके से काम करेगा?
प्रशांत कर्मकार

@PrashantKarmakar हाँ, जबकि readअप्रत्याशित व्यवहार हो सकता है। आपको mkdir और mv कमांड में वेरिएबल्स को भी उद्धृत करना चाहिए।
मुरु

इसका परीक्षण करें, यदि आप करेंगे:for i in *; do printf "%s\n" "$i"; done; for i in $(ls -d); do printf "%s\n" "$i"; done
मुरु

2

यदि आपके पास पर्ल का नाम / prename स्थापित है:

rename 's!(.*)\.(\w+)$! mkdir($2); "$2/$&"!ge'  *
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.