निर्दिष्ट निर्देशिका आकार में बड़ी निर्देशिका पेड़ का विभाजन?


11

मेरे पास एक डाइरेक्टरी ट्री है जिसे मैं ऑप्टिकल डिस्क में बैकअप लेना चाहता हूं। दुर्भाग्य से, यह किसी एक डिस्क के आकार से अधिक है (यह लगभग 60GB है)। मैं एक ऐसी स्क्रिप्ट की तलाश कर रहा हूं, जो इस पेड़ को कड़ी कड़ी या व्हाट्सएप (मूल अछूता छोड़कर) के साथ उचित आकार के टुकड़ों में विभाजित हो। मैं फिर इन काटने के आकार के पेड़ों को बैकअप प्रक्रिया में जोड़ सकता हूं (PAR2 अतिरेक जोड़ें, आदि)।

यह एक फैंसी स्क्रिप्ट नहीं है, लेकिन ऐसा लगता है कि यह पहले से ही हो सकता है। सुझाव?

(स्पैनिंग और राइटिंग इन वन स्टेप एक नो-गो है क्योंकि मैं फाइलों के जलने से पहले अधिक सामान करना चाहता हूं।)


क्या आपने एक धुंधला लेखक पाने पर विचार किया है?
bsd

2
डीवीडी मीडिया अविश्वसनीय है ... मैं एक बाहरी ड्राइव की सिफारिश करूंगा, कार्बोनाइट जैसे ऑनलाइन बैकअप, या यदि मीडिया जल रहा है, तो कुछ par2सुरक्षा का उपयोग करें ।
हारून डी। मरास्को

जवाबों:


7

इसके लिए डिज़ाइन किया गया एक एप्लिकेशन मौजूद है: dirsplit

यह आमतौर पर cdrkitया dirsplitपैकेज में रहता है।

यह आसानी से K3b या अन्य GUI सॉफ्टवेयर के साथ डीवीडी बनाने के लिए लिंक वाले रेडी-टू-यूज़ फोल्डर बना सकता है


यह वास्तव में अच्छी तरह से काम किया। उबंटू में मैंने इसे genisoimageपैकेज में पाया ।
nograpes


2

मैंने एक बार इसी तरह के उद्देश्य के लिए एक बदसूरत स्क्रिप्ट बनाई थी। यह सिर्फ एक कीचड़ है, लेकिन जब मैंने इसे लिखा तो मैंने निष्पादन के समय या सावधानी की परवाह नहीं की। मुझे यकीन है कि चारों ओर एक ही अवधारणा के अधिक "उत्पादीकृत" संस्करण हैं, लेकिन अगर आप हैकिंग शुरू करने के लिए कुछ विचार या कुछ प्राप्त करना चाहते हैं, तो यहां जाता है (2008 में किया था, इसलिए अपने जोखिम पर उपयोग करें!): - )

#!/bin/sh -
REPO=/export/foton/PictureStore
LINKS=/export/foton/links
SPLITTIX=`date '+%y%m%d-%H%M'`

# kilobytes
DVDSIZE=4400000
PARTPREFIX="DVD-"
REPOSIZE=`du -sk -- ${REPO} | awk '{print $1}'`
NUMPARTS=`expr $REPOSIZE / $DVDSIZE`
SPLITDIR=${LINKS}/splits/${SPLITTIX}
mkdir -p -- "$SPLITDIR"

PARTNUM=1
PARTSIZ=0
DONESIZ=0
PARTNUM=`echo $PARTNUM | awk '{printf("%03x", $0)}'`
mkdir -p -- "${SPLITDIR}/${PARTPREFIX}${PARTNUM}"
for D in "${REPO}"/..?* "${REPO}"/.[!.]* "${REPO}"/*
do
  if [ ! -e "$D" ]; then continue; fi  # skip ..?*, .[!.]* and * if there are no matching files
  D=${D#$REPO/}
  D_SIZ=`du -sk -- "${REPO}/$D" | awk '{print $1}'`
  if test `expr $D_SIZ + $PARTSIZ` -le $DVDSIZE
  then
    # link to D in this part
    ln -s -- "$REPO/$D" "${SPLITDIR}/${PARTPREFIX}${PARTNUM}/$D"
    # adjust counters
    PARTSIZ=`expr $PARTSIZ + $D_SIZ`
    DONESIZ=`expr $DONESIZ + $D_SIZ`
  else
    # next part and link to D in that
    echo PART $PARTNUM: $PARTSIZ kb '(target' $DVDSIZE 'kb)'
    PARTNUM=`expr $PARTNUM + 1`
    PARTNUM=`echo $PARTNUM | awk '{printf("%03x", $0)}'`
    PARTSIZ=$D_SIZ
    DONESIZ=`expr $DONESIZ + $D_SIZ`
    mkdir -p -- "${SPLITDIR}/${PARTPREFIX}${PARTNUM}"
    ln -s -- "$REPO/$D" "${SPLITDIR}/${PARTPREFIX}${PARTNUM}/$D"
  fi
done
echo "wrote $DONESIZ kb in $PARTNUM parts in $SPLITDIR"

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


मैंने फ़ाइल नाम (व्हॉट्सएप, प्रारंभिक डैश और डॉट्स \[?*) में विशेष वर्णों का सामना करने के लिए आपकी स्क्रिप्ट में कुछ बदलाव किए हैं । पढ़ने का सुझाव: ls , $ VAR बनाम $ {VAR} के आउटपुट को पार्स न करें और न ही उद्धरण या उद्धरण दें । ध्यान दें कि मैंने परिणामी स्क्रिप्ट का परीक्षण नहीं किया है। यदि आप मेरे परिवर्तनों को नहीं समझते हैं, तो बेझिझक पूछें।
गाइल्स का SO- बुराई से रोकना '

@ गिल्स: मैंने 2008 से खूब पढाई की है; स्क्रिप्ट को ज्यादा जेनेरिक बनाने के लिए बदलाव अच्छा है। ( हालांकि, मैं इसके [विपरीत परिचय को नापसंद करता हूं test) ...
मैटबियानको

आपको उन अधिकांश वेरिएबल्स को कम करना चाहिए। सम्मेलन द्वारा, हम पर्यावरण चर (PAGER, EDITOR, SHELL, ...) और आंतरिक शेल चर को कैपिटल करते हैं। अन्य सभी चर नामों में कम से कम एक लोअरकेस अक्षर होना चाहिए। यह कन्वेंशन गलती से पर्यावरण और आंतरिक चर को ओवरराइड करने से बचता है।
क्रिस डाउन

2

मैंने एक बार इसी तरह की समस्या को हल करने के लिए एक पटकथा लिखी थी - मैंने इसे "डिस्ट्रीब्यूट" कहा था (आप स्क्रिप्ट का मुख्य कोड या मदद संदेश के साथ फाइल पढ़ सकते हैं , या इसे पैकेज के रूप में डाउनलोड कर सकते हैं ); इसके विवरण से :

वितरित - कई सीडी पर संकुल का संग्रह वितरित करें (विशेष रूप से APT के साथ भविष्य के उपयोग के लिए अच्छा)

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

प्रारंभ में वितरित संग्रह के लिए आवधिक अद्यतन `वितरण 'की मदद से जारी किए जा सकते हैं।

यह पूरी प्रक्रिया को कई चरणों में करता है: एक चरण में, यह मूल फाइलों के लिए सिर्लिंक का उपयोग करके फ़्यूरर डिस्क "लेआउट" बनाता है - ताकि आप हस्तक्षेप कर सकें और भविष्य की डिस्क के पेड़ को बदल सकें।

इसके उपयोग के बारे में विवरण स्क्रिप्ट द्वारा मुद्रित सहायता संदेश (या स्रोत कोड को देखकर) में पढ़ा जा सकता है।

यह एक अधिक पेचीदा उपयोग के मामले को ध्यान में रखते हुए लिखा गया था ("भिन्न" के रूप में अपडेट जारी करना - जोड़े गए नई फ़ाइलों का सेट - मूल रूप से दर्ज की गई फ़ाइलों का संग्रह), इसलिए इसमें एक अतिरिक्त प्रारंभिक चरण शामिल है, अर्थात् "फिक्सिंग" "फ़ाइलों के संग्रह की वर्तमान स्थिति (सादगी के लिए, यह फ़ाइलों के मूल संग्रह को सहानुभूति के माध्यम से दोहराती है, संग्रह के राज्यों को बचाने के लिए एक विशेष कार्य स्थान में; फिर, भविष्य में कुछ समय के लिए; फ़ाइलों के संग्रह की भविष्य की वर्तमान स्थिति और इस सहेजी गई स्थिति के बीच एक अंतर बनाने में सक्षम होगा)। इसलिए, यद्यपि आपको इस सुविधा की आवश्यकता नहीं है, आप इस प्रारंभिक चरण AFAIR को छोड़ नहीं सकते।

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

APT- संबंधित सामान वैकल्पिक है, इसलिए इस बात पर ध्यान न दें कि यदि आपको इसकी आवश्यकता नहीं है तो यह APT द्वारा उपयोग किए जाने वाले पैकेज संग्रह तैयार कर सकता है।

यदि आप रुचि रखते हैं, तो निस्संदेह, इसे अपनी आवश्यकताओं को फिर से लिखने या सुधार का सुझाव देने के लिए स्वतंत्र महसूस करें।

(कृपया ध्यान दें कि पैकेज में अतिरिक्त उपयोगी पैच शामिल हैं जो ऊपर दिए गए गिट रेपो में प्रस्तुत कोड सूची में लागू नहीं हैं!)


मैंने अन्य चीजों को प्रस्तुत किया है - जो distributeकि इस बारे में पूछे गए आवश्यक कार्य को हल करती है।
इम्ज़ - इवान ज़खरीशेव

2

हमें यह नहीं भूलना चाहिए कि कार्य का सार वास्तव में काफी सरल है; जैसा कि हास्केल पर एक ट्यूटोरियल में रखा गया है (जो इस कार्य के लिए समाधान के माध्यम से काम के आसपास लिखा गया है, वृद्धिशील रूप से परिष्कृत)

अब आइए एक पल के लिए सोचें कि हमारा कार्यक्रम कैसे संचालित होगा और इसे छद्मकोड में व्यक्त करेंगे:

main = Read list of directories and their sizes.
       Decide how to fit them on CD-Rs.
       Print solution.

उचित लगता है? मुझे ऐसा लगा।

आइए अपने जीवन को थोड़ा सरल करें और अभी के लिए मान लें कि हम अपने कार्यक्रम के बाहर निर्देशिका आकार की गणना करेंगे (उदाहरण के लिए, " du -sb *") और स्टड से इस जानकारी को पढ़ें।

( सहयात्री गाइड से हास्केल, अध्याय 1 )

(अतिरिक्त, आपके प्रश्न में, आप परिणामी डिस्क लेआउट को ट्वीक (संपादित करना) कर सकते हैं, और फिर उन्हें जलाने के लिए एक उपकरण का उपयोग कर सकते हैं।)

आप अपने फ़ाइल संग्रह को विभाजित करने के लिए उस हास्केल ट्यूटोरियल से प्रोग्राम का एक सरल संस्करण फिर से उपयोग (अनुकूलित और पुनः उपयोग) कर सकते हैं।

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

आपको इसके कोड का कुछ उपयोग करने में मदद करने के लिए, यहां distribute( 380 लाइन पर ) के बैश-कोड का एक अंश दिया गया है, जो फाइलों के संग्रह को विभाजित करने के इस "आवश्यक" कार्य को करने के लिए कार्य करता है:

# Splitting:

function splitMirrorDir() {
  if [[ ! -d "$THIS_BASES_DIR/$BASE/$type" ]]; then
    echo $"No base fixed for $type" >&2
    exit 1
  fi

  # Getting the list of all suitable files:
  local -a allFiles
  let 'no = 0' ||:
  allFiles=()
  # no points to the next free position in allFiles
  # allFiles contains the constructed list
  for p in "$THIS_BASES_DIR/$BASE/$type"/*.rpm; do
      if [[ ! -e "$p" ]]; then
      # fail on non-existent files
      echo $"Package file doesn't exist: " "$p" >&2
      return 1 
      fi
      if [[ "$ONLY_REAL_FILES" == "yes" && ! -f "$p" ]]; then
      continue
      fi
      if [[ "$DIFF_TO_BASE" ]]; then
          older_copy="$DIFF_TO_BASE/$type/${p##*/}" # using shell param expansion instead of `basename' to speed up
          if [[ -h "$older_copy" || -a "$older_copy" ]]; then
          continue
      fi
      fi
      allFiles[$(( no++ ))]="$p"
  done
  readonly -a allFiles

  # Splitting the list of all files into future disks:
  # 
  local -a filesToEat allSizes
  let 'no = 0' ||:
  filesToEat=()
  allSizes=($(getSize "${allFiles[@]}"))
  readonly -a allSizes
  # allSizes contains the sizes corrsponding to allFiles
  # filesToEat hold the constructed list of files to put on the current disk
  # no points to the next free position in filesToEat
  # totalSize should hold the sum of the sizes 
  #  of the files already put into filesToEat;
  #  it is set and reset externally.
  for p in "${allFiles[@]}"; do 
      if (( totalsize + ${allSizes[$(( no ))]} > CDVOLUME )); then
      eatFiles "${filesToEat[@]}"
          filesToEat=()
          finishCD
      startTypedCD
    fi
      let "totalsize += ${allSizes[$(( no ))]}" ||:
      filesToEat[$(( no++ ))]="$p"
  done
  eatFiles "${filesToEat[@]}"
}

function eatFiles() {
    #{ oldIFS="$IFS"; IFS=$'\n'; echo "$FUNCNAME: args: " "$*" | head >&2;  IFS="$oldIFS"; }
    zeroDelimited "$@" | xargs -0 --no-run-if-empty \
    cp -s \
    --target-dir="$THIS_LAYOUTS_DIR/cd$(( cdN ))/$PREFIX/$type$DOT_SUFFIX"/ \
    --
}

function startTypedCD() {
#  set -x
  mkdir -p "$THIS_LAYOUTS_DIR/cd$(( cdN ))/$PREFIX/$type$DOT_SUFFIX"
  start_action $" %s with %s" "$(( cdN ))" "$type"
#  set +x
}

function finishCD() {

( पंक्ति 454 के बाद और पढ़ें )

ध्यान दें कि eatFilesफ़ंक्शन भविष्य के डिस्क को उन पेड़ों के रूप में तैयार करता है जहां पत्ते वास्तविक फ़ाइलों के लिए सीमलिंक होते हैं। तो, यह आपकी आवश्यकता को पूरा कर रहा है कि आपको जलने से पहले लेआउट को संपादित करने में सक्षम होना चाहिए। mkisofsउपयोगिता जो वास्तव में के कोड में कार्यरत है सिमलिंक पालन करने के लिए एक विकल्प है, मेरी mkisoसमारोह

प्रस्तुत स्क्रिप्ट (जिसे आप अपनी आवश्यकताओं के लिए ले सकते हैं और फिर से लिख सकते हैं!) सरलतम विचार का अनुसरण करते हैं: फाइलों के आकार (या, अधिक सटीक रूप से, पैकेज के मामले में distribute) के लिए बस जिस क्रम में वे सूचीबद्ध थे, डॉन किसी भी व्यवस्था नहीं करते।

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

पहले से ही पर्याप्त हैं। चलो कुछ सीडी पैक करते हैं।

जैसा कि आप पहले ही पहचान चुके होंगे, हमारी समस्या एक शास्त्रीय है। यह एक कहा जाता है "नेप्सेक समस्या" ( यह गूगल , यदि आप नहीं जानते कि यह पहले से ही क्या है। 100000 से अधिक लिंक कर रहे हैं)।

आइए लालची समाधान से शुरू करें ...

( अध्याय 3 और आगे में पढ़ें ।)

अन्य स्मार्ट उपकरण

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


1

backup2l इस काम का एक बहुत कुछ कर सकते हैं। यहां तक ​​कि अगर आप सीधे पैकेज का उपयोग नहीं करते हैं, तो आपको इसके कुछ स्क्रिप्ट विचार मिल सकते हैं।


0

rarArchiver स्वचालित रूप से संग्रहीत कर इसके साथ एक विशिष्ट आकार के टुकड़ों में अप बनाता है विभाजित करने के लिए निर्देश दिए जा सकती है -vsizeझंडा।

उस निर्देशिका वृक्ष का नाम देते fooहुए कहा, 500 मेगाबाइट एप्पी को आप निर्दिष्ट करेंगे
rar a backup.rar -v500m foo/


2
थान क्यों रार? टार (+ bz2) + विभाजन * निक्स के लिए अधिक देशी दृष्टिकोण है।
आरवी

"बाइट-साइज़ के पेड़" rarतब तक बहुत अच्छे नहीं लगते , जब तक कि आप प्रत्येक "पार्ट" को फिर से अपनी डायरेक्टरी में अनपैक नहीं करते हैं, जो कि निश्चित रूप से काम नहीं करेगा, क्योंकि पार्ट्स इस तरह से डिज़ाइन नहीं किए गए हैं, और फ़ाइल सीमाओं पर विभाजित नहीं हैं।
मैटबियनको

1
अगर उन उपकरणों के बारे में बात की जाए जो tar+ समान splitपरिणाम देते हैं, तो वहाँ भी dar है ; यहाँ इसकी प्रासंगिक विशेषता के बारे में एक टिप्पणी है: "(SLICES) यह कई हटाने योग्य मीडिया पर एक संग्रह को विभाजित करने में सक्षम होने के लिए डिज़ाइन किया गया था जो भी उनकी संख्या है और जो भी उनका आकार है"। tar+ की तुलना में split, मैं मानता हूं, यह संग्रहीत फ़ाइलों तक पहुंचने के कुछ आसान तरीकों की अनुमति देता है। (BTW, इसकी एक विशेषता भी है distribute: "DIFFERENTIAL BACKUP" & "DIRECTORY TREE SNAPSHOT", लेकिन किसी को यह पसंद नहीं हो सकता है कि परिणाम एक विशेष प्रारूप हो, dir ट्री के साथ ISO नहीं।)
imz - Ivan Zakharyaschev
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.