एक नेस्टेड निर्देशिका समतल


71

यह शायद बहुत सरल है, लेकिन मैं इसका पता नहीं लगा सकता। मैं इस तरह एक निर्देशिका संरचना है (dir2 dir1 के अंदर है):

/dir1
    /dir2 
       |
        --- file1
       |
        --- file2

इस तरह से निर्देशक संरचना को att समतल ’करने का सबसे अच्छा तरीका क्या है, फाइल 1 और फाइल 2 को डीआईआर 1 में प्राप्त करना न कििर 2।


जवाबों:


75

आप इसे GNU findऔर GNU के साथ कर सकते हैं mv:

find /dir1 -mindepth 2 -type f -exec mv -t /dir1 -i '{}' +

मूल रूप से, जिस तरह से काम करता है अगर वह findपूरी निर्देशिका ट्री और प्रत्येक फ़ाइल ( -type f) के लिए जाता है जो शीर्ष-स्तरीय निर्देशिका ( -mindepth 2) में नहीं है, तो mvयह उस निर्देशिका को स्थानांतरित करने के लिए चलता है जिसे आप चाहते हैं ( -exec mv … +)। -tतर्क करने mvकी सुविधा देता है आप गंतव्य निर्देशिका पहले निर्दिष्ट करते हैं, जो की जरूरत है क्योंकि +के रूप -execडालता है सभी आदेश के अंत में स्रोत स्थानों। -iबनाता है mvडुप्लीकेट अधिलेखन से पहले पूछना; आप -fउन्हें बिना पूछे (या -nपूछने के लिए या अधिलेखित नहीं) को अधिलेखित करने के लिए स्थानापन्न कर सकते हैं ।

जैसा कि स्टीफन चेज़ेलस बताते हैं, उपरोक्त केवल GNU टूल के साथ काम करता है (जो कि लिनक्स पर मानक हैं, लेकिन अधिकांश अन्य सिस्टम नहीं हैं)। निम्नलिखित कुछ धीमा है (क्योंकि यह mvकई बार आह्वान करता है) लेकिन बहुत अधिक सार्वभौमिक:

find /dir1 -mindepth 2 -type f -exec mv -i '{}' /dir1 ';'

3
उपयोग करने के लिए संपादित किया गया है -exec +ताकि यह बड़ी संख्या में प्रक्रियाओं का निष्पादन न करेmv
रैंडम 832

1
@ Random832 और फिर से वापस जाने के लिए, क्योंकि + काम नहीं करता है। mvअंतिम तर्क के रूप में गंतव्य की आवश्यकता है, लेकिन अंतिम तर्क के रूप में स्रोत होगा। यहां तक कि अभ्यस्त खोजें स्वीकार वाक्य रचना आप के लिए (इसे बदल find: missing argument to `-exec')
derobert

1
@ Random832, लेकिन मुझे लगता mvहै कि -tहम एक का उपयोग कर सकते हैं, तो मैं इसे करने के लिए इसे बदल देंगे।
व्युत्पन्न

1
@Dom findडिफ़ॉल्ट रूप से छिपी (डॉट) फाइलों को प्रिंट करता है। गहराई उस निर्देशिका के सापेक्ष है जिसे आप खोजने के लिए पास करते हैं।
derobert

1
या find ./dir -mindepth 2 -type f -exec mv -f '{}' ./dir ';'यदि डुप्लिकेट ओवरराइड कर रहा है
Atav32

33

Zsh में:

mv dir1/*/**/*(.D) dir1

**/अनुक्रमणिका को आवर्ती रूप से हटा देता है। ग्लोब क्वालीफायर . केवल नियमित रूप से फ़ाइलों का मिलान, और Dसुनिश्चित करता है कि डॉट फ़ाइलें शामिल किए गए हैं (डिफ़ॉल्ट, फ़ाइलें जिसका नाम शुरू होता है एक साथ द्वारा .वाइल्डकार्ड से बाहर रखा गया मेल खाता है)। बाद में खाली निर्देशिकाओं को साफ करने के लिए, चलाएं rmdir dir1/**/*(/Dod)- /निर्देशिकाओं पर प्रतिबंध लगाता है, और odमैचों को गहराई से ऑर्डर करता है ताकि dir1/dir2/dir3पहले हटा दें dir1/dir2

यदि फ़ाइल नामों की कुल लंबाई बहुत बड़ी है, तो आप कमांड लाइन की लंबाई पर सीमा में चल सकते हैं। Zsh के पास बिल्डिंस हैं mvऔर rmdirजो इस सीमा से प्रभावित नहीं हैं: zmodload zsh/filesउन्हें सक्षम करने के लिए चलाएं ।

केवल POSIX टूल के साथ:

find dir1 -type f -exec mv {} dir1 \;
find dir1 -depth -exec rmdir {} \;

या (क्योंकि यह प्रत्येक फ़ाइल के लिए एक अलग प्रक्रिया चलाने के लिए नहीं है तेजी से)

find dir1 -type f -exec sh -c 'mv "$@" dir1' _ {} +
find dir1 -depth -exec rmdir {} +

1
यह स्वीकृत उत्तर होना चाहिए! विशेष रूप से संक्षिप्त ज़ीश संस्करण के साथ।
Adamski

3

ऐसा करने का प्रयास करें:

cp /dir1/dir2/file{1,2} /another/place

या file[0-9]*उपडिर में मेल खाने वाली प्रत्येक फाइल के लिए :

cp /dir1/dir2/file[0-9]* /another/place

Http://mywiki.wooledge.org/glob देखें


मुझे इसका संकेत देना चाहिए था, लेकिन मुझे {}अपनी वास्तविक समस्या में उपयोग करने के लिए कई फाइलें हैं ।
कछुआ

मेरा दूसरा समाधान देखें
गाइल्स क्वेनोट

बिंगो। सहायता के लिए धन्यवाद। यह निश्चित रूप से सबसे अच्छा समाधान है।
कछुए

2

मैंने दो फ़ंक्शन लिखे जिनका आप एक साथ उपयोग कर सकते हैं, बस, आप एक -maxdepth $VALपैरामीटर जोड़कर डायरेक्टरी लेवल को सीमित कर सकते हैं ।

# This scripts flattens the file directory
# Run this script with a folder as parameter:
# $ path/to/script path/to/folder

#!/bin/bash

rmEmptyDirs(){
    local DIR="$1"
    for dir in "$DIR"/*/
    do
        [ -d "${dir}" ] || continue # if not a directory, skip
        dir=${dir%*/}
        if [ "$(ls -A "$dir")" ]; then
            rmEmptyDirs "$dir"
        else
            rmdir "$dir"
        fi
    done
    if [ "$(ls -A "$DIR")" ]; then
        rmEmptyDirs "$DIR"
    fi
}

flattenDir(){
    local DIR="$1"
    find "$DIR" -mindepth 2 -type f -exec mv -i '{}' "$DIR" ';'
}

read -p "Do you wish to flatten folder: ${1}? " -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
    flattenDir "$1" &
    rmEmptyDirs "$1" &
    echo "Done";
fi

यार, मैंने सिर्फ पथ तर्क को भूलकर आपकी स्क्रिप्ट का दुरुपयोग किया है, कि वास्तव में मेरे सर्वर को गड़बड़ कर दिया है। ठीक है, मैं वह व्यक्ति हूं जो चीजों को कॉपी करता है और उनका दुरुपयोग करता है, लेकिन दोस्तों, समझदार बनो और स्क्रिप्ट पर चेक / पुष्टिकरण
जोड़ो

ओह! सुन कर दुख हुआ। आशा है कि आपके पास बैकअप होगा ... मैंने भविष्य की सुरक्षा के लिए एक पुष्टिकरण जोड़ा।
ब्रूनो

धन्यवाद @Bruno इस तरह से बेहतर है। मेरा सर्वर अभी भी त्रुटिपूर्ण रूप से चल रहा है, मैंने "फ्लैटन" भाग के लिए खाली निर्देशिकाओं को हटाने के लिए टिप्पणी की (और वह मेरी त्रुटि थी) रूट, जब तक कि मैंने एक त्रुटि नहीं देखी, जिसने मुझे स्क्रिप्ट चलाना बंद कर दिया।
dulgan

1

इस प्रश्न के लिए लोकप्रिय उत्तर पर विस्तार करना, क्योंकि मेरे पास उसी नाम की फ़ाइलों वाली निर्देशिका को समतल करने के लिए उपयोग-मामला था।

dir1/
├── dir2
   └── file
└── dir3
    └── file

इस स्थिति में, निर्देशिका संरचना को समतल करने और नाम के संघर्ष को संभालने के लिए वांछित परिणाम प्राप्त नहीं करने के लिए -i( --interactive) विकल्प पारित किया गया mv। तो यह बस --backup=t(बराबर --backup=numbered) के साथ बदल दिया है । Https://www.gnu.org/software/coreutils/manual/coreutils.html#Backup-options पर उपलब्ध -b( --backup) विकल्प पर अधिक प्रलेखन ।

जिसके परिणामस्वरूप:

find dir1/ -mindepth 2 -type f -exec mv -t dir1/ --backup=t '{}' +

कौन सी पैदावार:

dir1/
├── dir2
├── dir3
├── file
└── file.~1~

1

टार और जिप दोनों को शामिल करने की क्षमता है और फिर एक निर्देशिका संरचना को दूर करना है, इसलिए मैं जल्दी से एक नेस्टेड के साथ समतल करने में सक्षम था

tar -cvf all.tar *

इसके बाद all.tar को एक नए स्थान पर ले जाया जाता है

tar -xvf all.tar --strip=4

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