নেস্টেড ডিরেক্টরিকে সমতল করা


71

এটি সম্ভবত খুব সহজ, তবে আমি এটি বুঝতে পারি না। আমার এই জাতীয় ডিরেক্টরি কাঠামো রয়েছে (dir2 dir1 এর অভ্যন্তরে রয়েছে):

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

এই পরিচালক কাঠামোকে কীভাবে 'সমতল' করা যায় তার সেরা উপায়টি কীভাবে এইভাবে ফাইল 1 এবং ফাইল 2 dir1 নয় dir2 এ পাওয়া যায়।


উত্তর:


75

আপনি জিএনইউ findএবং জিএনইউ দিয়ে এটি করতে পারেন 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কোনো সদৃশ overwrite করার আগে জিজ্ঞাসা; আপনি -fজিজ্ঞাসা -nনা করে এগুলি ওভাররাইটের বিকল্প করতে পারেন (বা জিজ্ঞাসা বা ওভাররাইট না করে)।

স্টিফেন চেজেলাস যেমন উল্লেখ করেছেন, উপরেরগুলি কেবল জিএনইউ সরঞ্জামগুলির সাথে কাজ করে (যা লিনাক্সের উপর স্ট্যান্ডার্ড, তবে অন্যান্য সিস্টেমে নয়)। নিম্নলিখিতটি কিছুটা ধীরে ধীরে (কারণ এটি mvএকাধিকবার আহ্বান জানায় ) তবে আরও অনেকগুলি সার্বজনীন:

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

3
ব্যবহারের জন্য সম্পাদিত হয়েছে -exec +যাতে এটি প্রচুর সংখ্যক প্রক্রিয়া mv
সম্পাদন

1
@ র্যান্ডম 832 এবং আবার ফিরতে চলেছে, কারণ + কাজ করে না। mvচূড়ান্ত যুক্তি হিসাবে গন্তব্য প্রয়োজন, তবে + চূড়ান্ত যুক্তি হিসাবে উত্স থাকবে। এমনকি আপনি এটিকে ( ) এ পরিবর্তিত বাক্য গঠন গ্রহণ করতে পারবেন নাfind: missing argument to `-exec'
ডারউবার্ট

1
@ র্যান্ডম 832 তবে আমি মনে করি যে আমাদের ব্যবহার করতে পারে mvএমন একটি আছে -t, তাই আমি এটি এটিতে পরিবর্তন করব।
ডারোবার্ট

1
@ ডোম findডিফল্টরূপে লুকানো (বিন্দু) ফাইল মুদ্রণ করে। গভীরতা আপনি যে ডিরেক্টরিটি সন্ধানের জন্য পাস করেছেন তার সাথে সম্পর্কিত।
ডারোবার্ট

1
অথবা find ./dir -mindepth 2 -type f -exec mv -f '{}' ./dir ';'যদি ডুপ্লিকেটগুলি ওভাররাইড করা হয়
আতভ 32

33

জেডএসে:

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

**/পুনরাবৃত্তভাবে উপ-ডিরেক্টরিগুলি অনুসরণ করে। গ্লোব কোয়ালিফায়ার কেবল .নিয়মিত ফাইলগুলির সাথে মেলে এবং Dডট ফাইলগুলি অন্তর্ভুক্ত করার বিষয়টি নিশ্চিত করে (ডিফল্টরূপে, ফাইলগুলির নাম যার সাথে শুরু হয় .ওয়াইল্ডকার্ডের ম্যাচগুলি থেকে বাদ দেওয়া হয়)। এরপরে এখন-খালি ডিরেক্টরিগুলি পরিষ্কার করার জন্য, চালান rmdir dir1/**/*(/Dod)- /ডিরেক্টরিগুলিতে সীমাবদ্ধ রাখুন এবং odম্যাচগুলির গভীরতায় প্রথমে অর্ডার করুন যাতে dir1/dir2/dir3আগে অপসারণ করা যায় dir1/dir2

যদি ফাইলের নামগুলির মোট দৈর্ঘ্য খুব বেশি হয়, আপনি কমান্ড লাইনের দৈর্ঘ্যের একটি সীমাবদ্ধতায় চলে যেতে পারেন। Zsh এর জন্য বিল্টিন রয়েছে mvএবং rmdirযা এই সীমাবদ্ধতার দ্বারা প্রভাবিত হয় না: zmodload zsh/filesএগুলি সক্ষম করতে চালান ।

কেবল পসিক্স সরঞ্জাম সহ:

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
এটি গ্রহণযোগ্য উত্তর হওয়া উচিত! বিশেষত সংক্ষিপ্ত zsh সংস্করণ সহ।
অ্যাডামস্কি

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 দেখুন


আমার এটি ইঙ্গিত করা উচিত ছিল, তবে {}আমার আসল সমস্যায় আমার অনেকগুলি ফাইল ব্যবহার করতে হবে to
কচ্ছপ

আমার দ্বিতীয় সমাধান দেখুন
গিলস কুইনট

বিঙ্গো। সাহায্যের জন্য ধন্যবাদ. এটি অবশ্যই সেরা সমাধান।
টার্টল

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

মানুষ, আমি পথের তর্কটি ভুলে গিয়ে কেবল আপনার স্ক্রিপ্টটির অপব্যবহার করেছি, যা সত্যিই আমার সার্ভারটিকে ফাক করেছে। ঠিক আছে, আমি সেই লোক, যিনি পেস্ট জিনিসগুলি অনুলিপি করেন এবং তাদের অপব্যবহার করেন, তবে ছেলেরা, বুদ্ধিমান
হোন

উপস! আমি এটা শুনে দুঃখিত. আশা করি আপনার একটি ব্যাকআপ আছে ... আমি ভবিষ্যতের সুরক্ষার জন্য একটি নিশ্চিতকরণ যুক্ত করেছি।
ব্রুনো

ধন্যবাদ @ ব্রুনো যে এইভাবে আরও ভাল। আমার সার্ভারটি এখনও নির্দ্বিধায় চলছে, আমি "ফ্ল্যাটেন" অংশটি মন্তব্য করেছি কেবল খালি ডিরেক্টরিগুলি পুনরাবৃত্তভাবে মুছে ফেলতে (এবং এটি ছিল আমার ত্রুটি) মূলটি, যতক্ষণ না আমি কোনও ত্রুটি দেখি যা আমাকে স্ক্রিপ্টটি চালানো বন্ধ করে দেয়।
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

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.