Cp का उपयोग करके एक आदर्श तरीके से पुनरावर्ती रूप से फ़ोल्डर की प्रतिलिपि कैसे बनाएं?


46

जब मैं उपयोग करता हूं

cp -R inputFolder outputFolder

परिणाम संदर्भ-निर्भर है :

  1. यदि outputFolderमौजूद नहीं है, तो यह बनाया जाएगा, और क्लोन फ़ोल्डर पथ होगा outputFolder
  2. यदि outputFolderमौजूद है, तो बनाया गया क्लोन होगाoutputFolder/inputFolder

यह भयानक है , क्योंकि मैं कुछ इंस्टॉलेशन स्क्रिप्ट बनाना चाहता हूं, और यदि उपयोगकर्ता इसे दो बार गलती से चलाता है, तो उसने outputFolderपहली बार बनाया होगा , फिर दूसरे रन पर सभी सामान एक बार फिर से बनाए जाएंगे outputFolder/inputFolder

  • मैं हमेशा पहला व्यवहार चाहता हूं: मूल (एक भाई के रूप में) के बगल में एक क्लोन बनाएं।
  • मैं cpपोर्टेबल होना चाहता हूं (जैसे MINGW के पास rsyncशिप नहीं है )
  • मैंने जाँच की cp -R --parentsलेकिन यह डाइरेक्टरी ट्री के सारे रास्ते को फिर से बनाता है (इसलिए क्लोन नहीं होगा outputFolderलेकिन some/path/outputFolder)
  • --remove-destinationया --updateमामले 2 में कुछ भी नहीं बदला है, फिर भी चीजें कॉपी की जाती हैंoutputFolder/inputFolder

क्या इसके अस्तित्व के लिए पहली जाँच के बिना ऐसा करने का एक तरीका है outputFolder(यदि फ़ोल्डर तब मौजूद नहीं है ...) या उपयोग कर रहा है rm -rf outputFolder?

क्या करने के लिए सहमत, पोर्टेबल UNIX तरीका है?



2
उन विकल्पों में से कुछ POSIX नहीं हैं, इसलिए आपने जिन लोगों की कोशिश की है वे बहुत पोर्टेबल नहीं हैं। यदि आप पोर्टेबिलिटी की थोड़ी कमी के साथ रह सकते हैं, तो उपयोग क्यों नहीं rsync?
मूरू

1
यदि आपको उपयोग करने की आवश्यकता नहीं है cp, तो tarपेड़ों को कॉपी करने के लिए दो आदेशों के बीच पाइपिंग एक अच्छा विश्वसनीय तरीका है।
आर ..

@R .. क्या आप एक उदाहरण दे सकते हैं? @ मैं इस तरह से MINGW में काम करना चाहूंगा जिसके पास rsyncशिप नहीं है ।
jakub.g

GNU टार के साथ, tar -C input -cf - . | tar -C output -xf -काम करता है। -Cवर्किंग डाइरेक्टरी को बदल देता है, लेकिन यह एक मानक विकल्प नहीं है, इसलिए यदि इसका समर्थन नहीं किया गया है तो आपको शुरू करने के लिए सही कार्य निर्देशिकाओं में दो टार चलाने की आवश्यकता है, जैसे ( cd input && tar -cf - . ) | ( cd output && tar -xf - )कि यदि आप विंडोज के साथ काम कर रहे हैं तो मैं सिर्फ रोइमा के उत्तर का उपयोग करूंगा।
आर ..

जवाबों:


54

इसके बजाय इसका उपयोग करें:

cp -R inputFolder/. outputFolder

यह ठीक उसी तरह से cp -R aaa/bbb cccकाम करता है, जो कहता है, काम करता है: यदि cccमौजूद नहीं है, तो इसे bbbऔर इसकी सामग्री की नकल के रूप में बनाया जाता है ; लेकिन अगर cccपहले से मौजूद है तो उसकी सामग्री और उसकी सामग्री ccc/bbbके रूप में बनाया जाता है bbb

इस के लगभग किसी भी उदाहरण के bbbलिए अवांछनीय व्यवहार देता है जिसे आपने अपने प्रश्न में नोट किया था। हालांकि, इस विशिष्ट स्थिति में bbbसिर्फ .इतना aaa/bbbहै aaa/., वास्तव में है , जो बदले में वास्तव में सिर्फ aaaएक और नाम से है। इसलिए हमारे पास ये दो परिदृश्य हैं:

  1. ccc अस्तित्व में नहीं है:

    आदेश cp -R aaa/. cccका अर्थ है "बनाने cccऔर की सामग्री की प्रतिलिपि aaa/.में ccc/., यानी नकल aaaमें ccc

  2. ccc अस्तित्व में है:

    आदेश cp -R aaa/. cccका अर्थ है "की सामग्री की प्रतिलिपि aaa/.में ccc/., यानी नकल aaaमें ccc


3
हुह, यह मेरे लिए एक नया है, लेकिन यह काम करने लगता है! यह कहीं भी प्रलेखित है?
इल्मरी करोनें

1
मैंने inputFolder/.इसके बजाय परीक्षण किया है inputFolderऔर वास्तव में यह मेरे लिए विंडोज / गिट बैश पर काम करता है। (यह सिर्फ एक अनुगामी के साथ काम नहीं करता है /, मुझे स्लैश के बाद भी डॉट की आवश्यकता है)। मैंने +1 दिया क्योंकि यह दिलचस्प है, हालांकि सार्वजनिक कोड में इसका उपयोग करना शायद थोड़ा मुश्किल है :)
jakub.g

@ इलमारीजोरेन को स्पष्ट रूप से प्रलेखित करने की आवश्यकता नहीं है। स्पष्टीकरण के माध्यम से पालन करें और आप देखेंगे कि यह कैसे "नियमों का पालन करता है"।
रोज़

18

फ़ोल्डर की प्रतिलिपि न करें, केवल सामग्री की प्रतिलिपि बनाएँ:

## Create the target directory. The -p suppresses error messages
## if the directory already exists
mkdir -p outputFolder

## Copy the contents recursively, this will not recreate the parent
cp -R inputfolder/* outputfolder/

इस तरह से आप दोनों यह सुनिश्चित करते हैं कि लक्ष्य निर्देशिका पहली बार बनाई गई है जब स्क्रिप्ट चलती है और दूसरी बार चलने पर समस्या से बचें।

क्रिस डाउन बहुत सही ढंग से बताता है कि बैश में, यह उन फ़ाइलों को छोड़ देगा, जिनका नाम a से शुरू होता है .। इससे बचने के लिए, आप shopt -s dotglobऊपर दिए गए कमांड को चलाने से पहले चला सकते हैं ।

दोनों -pके लिएmkdir और -Rके लिएcp POSIX द्वारा परिभाषित कर रहे तो यह पूरी तरह से पोर्टेबल होना चाहिए।


6
नोट: यह फाइलों को कॉपी नहीं कर सकता है .। बैश में, आप इसके dotglobलिए उपयोग कर सकते हैं ।
क्रिस डाउन

2
ध्यान दें कि इनपुटफ़ोल्डर में निर्देशिका प्रविष्टियों की संख्या बड़ी होने पर यह विफल होने की संभावना है, क्योंकि ग्लोब विस्तार अधिकतम कमांड लाइन की लंबाई को पार कर सकता है।
टिम कट्स

11

-Tकरने के लिए विकल्प का प्रयास करें cp। यह GNU कोरुटिल्स cpसंस्करण 8.22 में मौजूद है ; यह उस के बाहर पोर्टेबल नहीं हो सकता है।


1
हाँ, ऐसा लगता है कि यह वही है जो मैं चाहता था: cp -T( cp --no-target-directory)। unix.stackexchange.com/questions/94831/… दुर्भाग्य से मेरा संस्करण cpबहुत पुराना है।
jakub.g

1
+1 आज ही इस्तेमाल किया। -uयह आलसी बनाने के लिए जोड़ने के लिए एक बढ़िया विकल्प है।
PSkocik

4

आप यह भी उपयोग कर सकते हैं rsync:

rsync -uav inputFolder/ outputFolder/

(ध्यान दें कि स्लैश, विशेष रूप से पहले एक के बाद)


0

मेरी राय में, कुछ भी सरल और अधिक पोर्टेबल नहीं है rm -rf outputFolder। इसलिए, मैं हमेशा उसी के साथ रहता हूं। मैं समझता हूं कि आपका प्रश्न अलग है, लेकिन मुझे लगता है कि यह सबसे अच्छा अभ्यास है।


यदि लक्ष्य रखने के लिए आवश्यक विशिष्ट अनुमतियाँ या स्वामी हैं, तो यह विफल रहता है। या अगर यह एक सिमलिंक था।
रोइमा

1
प्रश्न यह चाहता है कि परिणाम cpवही हो, जब निर्देशिका मौजूद नहीं है और जब मौजूद है तो दोनों ही। तो, आप किस बारे में बात कर रहे हैं?

cpआदेश के रूप में ओ पी द्वारा दिए गए अनुमतियाँ (या टाइम स्टांप) नहीं रखता।
रोएमा

0

आप कमांड के -tविकल्प का उपयोग कर सकते हैं cp:

cp -R inputFolder -t outputFolder

अब अगर टारगेट फोल्डर मौजूद नहीं है तो यह एक एरर फेंक देगा:

cp: failed to access ‘outputFolder’: No such file or directory

नोट के ऊपर कमांड inputFolderइसकी सामग्री के साथ कॉपी करेगा (और इसके अंदर सिर्फ सामग्री नहीं)

यदि आप इसे कॉपी करना चाहते हैं तो इसकी सामग्री inputFolderथोड़ी मुश्किल हो जाती है (क्योंकि आपको तारांकन का उपयोग करते समय शेल ग्लोबिंग का उपयोग करते समय सावधान रहना होगा)

cp -R  -t outputFolder/ -- inputFolder/*

अब अगर टारगेट फोल्डर मौजूद नहीं है तो यह एक एरर फेंक देगा:

cp: failed to access ‘outputFolder’: No such file or directory

के साथ काम करता है cp (GNU coreutils) 8.23

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