लिनक्स विलय फ़ोल्डर: rsync?


13

मेरे पास एक फ़ोल्डर की दो प्रतियां हैं

src/
dest/

मैं उन्हें मर्ज करना चाहता हूं, निम्नलिखित कर:

यदि कोई फ़ाइल केवल में है src, तो मैं चाहता हूं कि इसे स्थानांतरित कर दिया जाएdest

यदि कोई फ़ाइल केवल में है dest, तो मैं चाहता हूं कि यह आईई को अकेला छोड़ दिया जाए।

यदि कोई फ़ाइल दोनों में है और समान सामग्री (IE समान आकार और दिनांक) है, तो से हटा देंsrc

यदि कोई फ़ाइल दोनों में है और समान सामग्री नहीं है, तो पीछे छोड़ दें srcताकि मैं उन्हें मैन्युअल रूप से मर्ज कर सकूं।

केवल बहुत कम संख्या में फ़ाइलें (कुल फ़ाइलों का 0% और 5% के बीच) इस अंतिम श्रेणी में होनी चाहिए, लेकिन मुझे नहीं पता कि दोनों में और समान को दोनों में से कैसे अलग किया जाए, लेकिन अलग।

मैंने यह पता लगाने की कोशिश की है कि यह कैसे करना है rsyncलेकिन अभी तक कोई फायदा नहीं हुआ है।

जवाबों:


17

मैंने केवल सीमित कार्यक्षमता परीक्षण किया है, इसलिए कृपया इस आदेश (--dry-run) से सावधान रहें:

rsync -avPr --ignore-existing --remove-source-files src/ dest

कृपया ध्यान दें कि अनुगामी / जैसा कि स्वयं src की प्रतिलिपि बनाने के बजाय src में आ जाएगा, यह आपके मौजूदा पथ को बनाए रखना चाहिए।

-Remove-source-files-flag के साथ संयोजन में -ignore-मौजूदा ध्वज का उपयोग करके आप src से केवल उन फ़ाइलों को हटा देंगे जो src से srt तक किस्‍से में हैं, जो कि ऐसी फ़ाइलें हैं जो पहले केवल किस्‍मत में मौजूद नहीं थीं।

गैर-सिंक की गई फ़ाइलों को हटाने के लिए, वह वह है जो पहले से ही मौजूद है / जैसे कि src / में, आप उपयोग कर सकते हैं:

for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done

या

find src -type f -exec bash -c 'cmp -s "$0" "${0/#src/dest}" && rm "$0"' {} \;

यदि फ़ाइलनामों में व्हाट्सएप / नई लाइनें शामिल हो सकती हैं ... तो विशेष वर्णों के बारे में गिल्स की टिप्पणी के बारे में, निश्चित रूप से कुछ का ध्यान रखना चाहिए और कई समाधान हैं, सरलतम आरएम को पास करना होगा जो सभी विलोपन के लिए संकेत देगा। बशर्ते कि src /, या इसके मूल पथ को खोजने के लिए प्रदान किया जाता है, हालांकि, पूरी तरह से योग्य पथ को सभी फ़ाइल नामों में परिणाम और rm कमांडों द्वारा बिना उद्धृत किए ठीक से संभाला जाना चाहिए।


सुधार: वह आदेश src से फ़ाइलों को नहीं हटाएगा अगर एक समान प्रतिलिपि पहले से ही भाग्य में मौजूद है
तोक

हाँ :(। यह वह हिस्सा है जो मुझे पता लगाने में मुश्किल हो रहा है।
डेविड वनिल

2
खैर, अच्छी खबर यह है कि आप इसे बहुत परेशानी के बिना स्वतंत्र रूप से हल कर सकते हैं: for file in `find src/ -type f`; do diff $file `echo $file | sed 's/src/dest/'` && rm $file || echo $file; done(आप चाहें तो इसे छोड़ सकते || echo $fileहैं, यह पूर्णता के लिए शामिल है)
तोक

निफ्टी: यही मुझे चाहिए था। अपने उत्तर में संपादित करें, और मैं इसे स्वीकार करूँगा!
डेविड वनिल

@ टॉक: आपका आदेश उन फ़ाइल नामों को चोक कर देगा जिनमें विशेष वर्ण (व्हाट्सएप \?*[, प्रारंभिक -) हैं। आपको चर प्रतिस्थापन के आसपास दोहरे उद्धरण चिह्नों का उपयोग करने की आवश्यकता है , --फ़ाइल नाम से पहले उपयोगिताओं को पास करें, find … -exec …के आउटपुट को पार्स करने के बजाय उपयोग करें findrmमिश्रण में एक कमांड के साथ , यह आपदा के लिए एक नुस्खा है।
गिलेस एसओ- 1

6

यूनिसन वह उपकरण है जिसकी आप तलाश कर रहे हैं। यदि आप कोई पसंद करते हैं तो unison-gtk का प्रयास करें। लेकिन मुझे नहीं लगता कि यह समान फ़ाइलों को हटा देगा: दोनों निर्देशिकाओं के समान होने का प्रयास करें। फिर भी यह आसानी से 1) पहचानें कि कौन सी फाइलें कॉपी करनी हैं; 2) जिन्हें मैनुअल मर्ज की जरूरत है।


यह वही नहीं करता है जो ओपी पूछता है, लेकिन ऐसा लगता है कि यह ओपी के अंतिम लक्ष्य को पूरा करता है। +1
रयान सी। थॉम्पसन

+1 अफसोस की बात यह है कि मैं जिस सर्वर पर चल रहा हूं, उसमें यूनिसन स्थापित नहीं है, न ही मुझे इसे स्थापित करने की अनुमति है। लेकिन यह किसी और के लिए एक अच्छा जवाब हो सकता है।
डेविड वनिल

1
आप सीज़न से अनुपयोगी डाउनलोड कर सकते हैं ।upenn.edu/~bcpierce/ unison //download/… । इसे अपने घर निर्देशिका में कहीं स्थापित करें, यह सिर्फ एक फ़ाइल है।
जू मेइंग

2

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

cd src
find . -exec sh -c '
    set -- "/path/to/dest/$0"
    if [ -d "$0" ]; then #  the source is a directory 
      if ! [ -e "$1" ]; then
        mv -- "$0" "$1"  # move whole directory in one go
      fi
    elif ! [ -e "$0" ]; then  # the source doesn't exist after all
      :  # might happen if a whole directory was moved
    elif ! [ -e "$1" ]; then  # the destination doesn't exist
      mv -- "$0" "$1"
    elif [ -f "$1" ] && cmp -s -- "$0" "$1"; then  # identical files
      rm -- "$0"
    fi
  ' {} \;

एक और तरीका यह होगा कि यूनियन एक डायरेक्टरी को दूसरे से ऊपर कर दे, उदाहरण के लिए फियोनफ्स या यूनियनफ्यूज -फ्यूज

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