पुनरावर्ती निर्देशिका से विशेष रूप से नामित फ़ोल्डर कैसे निकालें, दूसरों को हटा दें?


10

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

x -> y -> z -> रन -> फ़ाइलें और दिशा-निर्देश यहाँ हैं

तो 4 निर्देशिकाएं हैं, जिनमें से 3 फाइलें (एक्स, वाई, जेड) की खाली हैं और केवल 1 उप-निर्देशिका हैं, और वहां निर्देशिका है जिसे मैं " रन " नाम देता हूं ।

मैं "रन" डायरेक्टरी को (हर चीज को मिलाकर) "रूट" लोकेशन पर ले जाना चाहता हूं, जहां मैंने अनजिप किया (यानी जहां "x" है, लेकिन "x" के अंदर नहीं)।

मान्यताओं: "रन" नाम का एक फ़ोल्डर मौजूद है, लेकिन मुझे नहीं पता कि इसे प्राप्त करने के लिए मुझे कितनी निर्देशिकाओं में "सीडी" करनी होगी (3 (x, y, z), 10 या अधिक हो सकते हैं। नाम अज्ञात भी हैं और x, y, z आदि नहीं होना चाहिए)।

मैं यह कैसे हासिल कर सकता हूं? मैंने इस प्रश्न के कई रूपों की कोशिश की लेकिन वे सभी विफल रहे।


1
मुझे डर है कि तस्वीर बहुत स्पष्ट नहीं है, नहीं। कृपया पाठ के स्क्रीनशॉट पोस्ट न करें । इसके बजाय, टेक्स्ट को सीधे अपने प्रश्न में पेस्ट करें और फ़ॉर्मेटिंग टूल का उपयोग करें । मैं आपकी तस्वीर में निर्देशिका का नाम भी नहीं पढ़ सकता। सभी मैं देख रहा हूँ एक मंद नीला कलंक है।
terdon

जवाबों:


14

किस बारे में

  find . -type d -name run -exec mv {} /path/to/X \;

कहाँ पे

  • / path / to / X आपकी गंतव्य निर्देशिका है
  • आप इसी जगह से शुरू करते हैं।
  • फिर खाली निर्देशिका निकालने के लिए अन्य उत्तर का उपयोग करें।

(साइड नोट --junk-pathsमें ज़िप में एक विकल्प होता है, या तो ज़िपिंग या अनज़िपिंग के दौरान)


7

मैं इसका bashउपयोग करते हुए करूंगा globstar। जैसा कि समझाया गया है man bash:

globstar
      If set, the pattern ** used in a pathname expansion con‐
      text will match all files and zero or  more  directories
      and  subdirectories.  If the pattern is followed by a /,
      only directories and subdirectories match.

इसलिए, निर्देशिका runको शीर्ष स्तर की निर्देशिका में ले जाने के लिए x, और फिर बाकी को हटा दें, आप कर सकते हैं:

shopt -s globstar; mv x/**/run/ x/  && find x/ -type d -empty -delete

shoptआदेश में सक्षम बनाता है globstarविकल्प। mv x/**/run/ x/नामित किसी भी उपनिर्देशिका चले जाएँगे run(ध्यान दें अगर वहाँ केवल एक ही है कि यह केवल काम करता है runके लिए निर्देशिका) xऔर findकिसी भी खाली निर्देशिका को नष्ट करेगा।

यदि आप चाहें तो आप पूरे काम को विस्तारित ग्लोबिंग के साथ खोल में कर सकते हैं, लेकिन मैं सुरक्षा जाल को प्राथमिकता देता हूं find -emptyसुनिश्चित करें कि कोई गैर-खाली निर्देशिका हटा दी गई है। अगर आपको इस बात की परवाह नहीं है, तो आप इसका उपयोग कर सकते हैं:

shopt -s globstar; shopt -s extglob; mv x/**/run/ x/ && rm -rf x/!(run)

6

निश्चित रूप से अधिक क्रिया, लेकिन एक चरण में काम करना:

मान लें कि आपके पास अजगर स्थापित है

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    # find your folder "run"
    for pth in [d for d in dirs if d == sys.argv[2]]:
        # move the folder to the root directory
        shutil.move(os.path.join(root, pth), os.path.join(dr, pth))
        # remove the folder (top of the tree) from the directory
        shutil.rmtree(os.path.join(dr, root.replace(dr, "").split("/")[1]))

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

  1. स्क्रिप्ट को एक खाली फ़ाइल में कॉपी करें, इसे इस रूप में सहेजें get_folder.py
  2. इसे रूट डायरेक्टरी के साथ चलाएं (अपने अनजैप्ड सामान को समेटते हुए) और तर्क के रूप में फ़ोल्डर का नाम "लिफ्ट" करें:

    python3 /full/path/to/get_folder.py /full/path/to/folder_containing_unzipped_dir run
    

और हो गया:

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें


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

कोई दिक्कत नहीं है। हो सकता है कि यह किसी और के लिए उपयोग हो। हालांकि क्यों उत्सुक? मुझे पूरा यकीन है कि कई एप्लिकेशन पहले से ही अजगर का उपयोग करते हैं।
जैकब व्लिजम

मुख्य रूप से .py फ़ाइल रखने के बाद से कहीं भी समस्याग्रस्त हो जाएगी क्योंकि मुझे यह मान लेना होगा कि यह हर लिनेक्स मशीन के लिए एक ही जगह है जो मेरी स्क्रिप्ट चला रही होगी (और मेरी स्क्रिप्ट कई प्लेटफार्मों पर चलाई गई है)।
इदोस

@ क्या सिर्फ उत्सुक, जो प्लेटफार्मों? अजगर काफी व्यापक है। मुझे नहीं लगता कि यह मैक ओएस एक्स पर डिफ़ॉल्ट रूप से स्थापित है, लेकिन अधिकांश लिनक्स वितरणों में यह होता है
सर्जियो कोलोडियाज़नी

4

पर्ल समाधान

#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
use File::Copy::Recursive qw(dirmove);

my @wanted;
find(sub{ -d $_ && $_ eq "run" && push @wanted,$File::Find::name}, $ARGV[0]);
dirmove("$wanted[0]","./run");

जिस तरह से यह काम सरल है: find()सबरूटीन को दिए गए डायरेक्टरी ट्री को पीछे से पीछे की ओर ले जाएगा, उस डायरेक्टरी को खोजें, जिसका नाम है runऔर इसे वांछित फ़ाइलनामों की श्रेणी में धकेलें। इस स्थिति में, हम मानते हैं कि सूची में केवल एक फ़ाइल होनी चाहिए, इस प्रकार एक बार कमांड पूरी होने पर, हम मॉड्यूल dirmove()से उपयोग करते हैं File::Copy::Recursive, और इसे वर्तमान कार्यशील निर्देशिका में ले जाते हैं जहां से स्क्रिप्ट को बुलाया गया था। इस प्रकार आपके मामले में आप इसे मूल निर्देशिका से कॉल करेंगे x

मूल निर्देशिका पेड़:

$ tree                                                                                                                   
.
└── levelone
    └── leveltwo
        └── levelthree
            └── run
                ├── file1
                ├── file2
                └── file3

परिणाम:

$ ~/find_dir.pl .  
$ tree 
.
├── levelone
│   └── leveltwo
│       └── levelthree
└── run
    ├── file1
    ├── file2
    └── file3
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.