एक और एक बनाने के बजाय निर्देशिका को अधिलेखित करने के लिए 'cp' को कैसे बाध्य करें?


107

मैं एक बैश स्क्रिप्ट लिखने की कोशिश कर रहा हूं जो मौजूदा निर्देशिका को अधिलेखित कर देगी। मेरे पास एक निर्देशिका है foo/और मैं bar/इसके साथ ओवरराइट करने की कोशिश कर रहा हूं । लेकिन जब मैं ऐसा करता हूं:

cp -Rf foo/ bar/

एक नई bar/foo/निर्देशिका बनाई गई है। मैं ऐसा नहीं चाहता। इसमें दो फाइलें हैं foo/; aऔर b। साथ ही समान नामों वाली फाइलें bar/भी हैं। मैं चाहता हूँ कि foo/aऔर foo/bको बदलने के लिए bar/aऔर bar/b

जवाबों:


122

आप -Tविकल्प का उपयोग करके ऐसा कर सकते हैं cp
के लिए मैन पेज देखें cp

-T, --no-target-directory
    treat DEST as a normal file

तो आपके उदाहरण के अनुसार, फ़ाइल संरचना निम्नलिखित है।

$ tree test
test
|-- bar
|   |-- a
|   `-- b
`-- foo
    |-- a
    `-- b
2 directories, 4 files

-vवर्बोज़ के लिए उपयोग करने पर आप स्पष्ट अंतर देख सकते हैं ।
जब आप सिर्फ -Rविकल्प का उपयोग करते हैं ।

$ cp -Rv foo/ bar/
`foo/' -> `bar/foo'
`foo/b' -> `bar/foo/b'
`foo/a' -> `bar/foo/a'
 $ tree
 |-- bar
 |   |-- a
 |   |-- b
 |   `-- foo
 |       |-- a
 |       `-- b
 `-- foo
     |-- a
     `-- b
3 directories, 6 files

जब आप विकल्प का उपयोग करते हैं तो -Tयह सामग्री को अधिलेखित कर देता है, गंतव्य को एक सामान्य फ़ाइल की तरह मानता है और निर्देशिका नहीं

$ cp -TRv foo/ bar/
`foo/b' -> `bar/b'
`foo/a' -> `bar/a'

$ tree
|-- bar
|   |-- a
|   `-- b
`-- foo
    |-- a
    `-- b
2 directories, 4 files

इससे आपकी समस्या का समाधान हो जाना चाहिए।


22
बस किसी के द्वारा इस मामले में
फंस जाने पर

9
यह स्पष्ट नहीं है कि यह उत्तर वह है जो ओपी की तलाश कर रहा है, हालांकि ऊपर दिए गए उदाहरण समस्या का सामना करते हैं ... -T विकल्प के साथ, फ़ाइलें जो एक मौजूदा लक्ष्य ( bar/) में हैं, लेकिन स्रोत में नहीं हैं ( foo/) छोड़ दिया जाएगा जगह में, इसलिए यह नहीं है कि ज्यादातर लोग निर्देशिका के एक पूर्ण अधिलेखित पर विचार करेंगे। अर्थात। यदि bar/bazपहले से मौजूद था, तो यह बाद में भी मौजूद रहेगा ...
robo

1
यह उत्तर op प्रश्न का उत्तर देता है, लेकिन यदि गंतव्य पहले से मौजूद है और आप इसमें मौजूद सामग्री को हटाना चाहते हैं, लेकिन स्रोत निर्देशिका नहीं है, तो इस मामले को संबोधित नहीं करता है। यह फ़ाइलों को एक स्थान से दूसरे स्थान पर कॉपी करने का अपेक्षित व्यवहार नहीं है। यह केवल उन लक्षित चीजों में ओवरराइट करता है जो स्रोत में भी हैं, यह उस लक्ष्य में कुछ भी नहीं छूता है जो स्रोत में नहीं है। आप इसे करने के लिए एक कमांड तैयार करके लक्ष्य फ़ोल्डर को साफ कर सकते हैं:rm -rf bar/* && cp -TRv foo/ bar/
theferrit32

1
मैं माइंड रीडर नहीं हूं ... मैं आगे स्पष्टीकरण नहीं देखता कि ओपी क्या देख रहा था, लेकिन यह जवाब था कि मैं (MEEEE) की तलाश कर रहा था
Assimilater

2
अगर कोई सबसे अधिक टिप्पणी में लिंक पर काम नहीं कर रहा है, तो यहां कोई भी काम नहीं कर रहा है, यहाँ है: web.archive.org/web/20170909193852/https://developer.apple.com/ ...
सल्फर

48

इसे दो चरणों में करें।

rm -r bar/
cp -r foo/ bar/

11
यह वास्तव में अब तक का एकमात्र उदाहरण है जो यह सुनिश्चित करेगा कि barसामग्री में समान है foo, न fooकि अन्य वस्तुओं से आइटम का संयोजन जो पहले से मौजूद हो सकता है bar। नीचे @Saurabh मेश्राम के अत्यधिक उत्कीर्ण उत्तर में यह समस्या है।
रोबो

1
इसका उपयोग करने में अतिरिक्त सावधानी बरतें, क्योंकि यह बार से सभी फाइलों को हटा देगा , यहां तक ​​कि छिपे हुए भी।
एलिया ग्रैडी

mac osx: rm -rf bar/; cp -r foo/ !$
माइकल डिम्मिट

1
यह हमेशा व्यवहार्य नहीं है ... या वांछित ... कल्पना करें कि क्या है fooऔर barबड़ी निर्देशिकाएं हैं ... हो सकता है barकि इसमें ऐसी फाइलें हों fooजो आप निकालना नहीं चाहते हैं। इसे एक यथार्थवादी उत्तर नहीं माना जाना चाहिए
असीमित्र

हालांकि मेरे लिए काम किया है, लेकिन सबसे अच्छा समाधान नहीं है क्योंकि फ़ाइल को foo में शामिल किया जा सकता है / लेकिन बार में नहीं / जो ऐसा करने के बाद हटा दिया जाएगा।
नाइटविट

46

यदि आप यह सुनिश्चित करना चाहते हैं कि इसके bar/समान foo/उपयोग हो , तो rsyncइसके बजाय उपयोग करें :

rsync -a --delete foo/ bar/

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

  • -a'आर्काइव मोड' है, जो विश्वासपूर्वक फाइलों को कॉपी करता foo/हैbar/
  • --deleteअतिरिक्त फ़ाइलों को अंदर foo/से भी नहीं हटाता bar/, यह सुनिश्चित bar/करता है कि समान समाप्त हो
  • यदि आप यह देखना चाहते हैं कि यह क्या कर रहा है, -vhक्रिया और मानव पठनीय के लिए जोड़ें
  • ध्यान दें: बाद में स्लैश fooकी आवश्यकता है, अन्यथा खुद को अधिलेखित करने के बजाय rsyncकॉपी करेगा । foo/bar/foo/bar/
    • (Rsync में निर्देशिका के बाद Slashes भ्रमित कर रहे हैं, अगर आपका रुचि रखते हैं, यहाँ स्कूप है वे rsync बताने के लिए उल्लेख करने के लिए। सामग्री बल्कि निर्देशिका से, निर्देशिका का ही तो से अधिलेखित करने के लिए। सामग्री की foo/की सामग्री पर bar/, हम दोनों पर एक स्लैश का उपयोग करें। यह भ्रामक है क्योंकि यह न तो स्लैश के साथ अपेक्षित रूप से काम करेगा , हालांकि, rsync चुपके से हमेशा गंतव्य पथ की व्याख्या करता है जैसे कि इसमें स्लैश है, भले ही यह स्रोत पर स्लैश की अनुपस्थिति का सम्मान करता है पथ। यह गंतव्य पथ पर स्वत: जोड़ा स्लेश मिलान करने के लिए, तो हम स्रोत पथ पर एक स्लेश जरूरत है हम कॉपी करना चाहते हैं, तो सामग्री की foo/में bar/नहीं बल्कि निर्देशिका से,foo/खुद के bar/रूप में लैंडिंग bar/foo।)

rsync बहुत शक्तिशाली और उपयोगी है, अगर आप इसके बारे में उत्सुक हैं कि यह और क्या कर सकता है (जैसे कि ssh पर नकल करना)।


1
इस उत्तर को cp -Tविकल्प की तुलना में बेहतर
मानें

18

इस cpकमांड का उपयोग करें :

cp -Rf foo/* bar/

9
यह उन फ़ाइलों को नहीं हटाता है जो बार में मौजूद हैं लेकिन foo में नहीं हैं।
आरा

5
पता नहीं तुम क्या मतलब है कि द्वारा। cpस्रोत से फ़ाइल को हटाने का आदेश क्यों होना चाहिए ?
शुभ

मेरी समझ यह थी कि जब आप किसी अन्य के साथ 'मौजूदा निर्देशिका को अधिलेखित' करते हैं, तो अंत में अधिलेखित निर्देशिका दूसरे की एक प्रति होनी चाहिए। अंतिम छोर पर Ie को foo की एक प्रति होना चाहिए, क्योंकि यह @ jonathan-wheeler answer के साथ होता है लेकिन अगर आपके पास फ़ाइल बार / c और कोई foo / c नहीं है तो बार / c डिलीट नहीं होता है। एक साइड नोट पर, मैंने अभी गौर किया है कि सौरभ मेश्राम के जवाब के साथ ऐसा नहीं है।
आरा

हो सकता है कि हम इस बात पर सहमत न हों कि मेरे लिए इसका अर्थ क्या है, यह मूल रूप से प्रतिस्थापित है, जबकि आपका मतलब हो सकता है? यह बताना मुश्किल है कि ओपी वास्तव में क्या चाहता है क्योंकि उसने केवल 2 फाइलों का उल्लेख किया है जो फू और बार दोनों में हैं।
आरा

यह सिंटैक्स छिपी हुई डॉट फ़ाइलों को भी अनदेखा करता है। बड़ी संख्या ग्लोब को भी उड़ा सकती है।
xpusostomos

13

निम्न आदेश यह सुनिश्चित करता है कि डॉटफ़ाइल्स (छिपी हुई फ़ाइलें) प्रतिलिपि में शामिल हैं:

$ cp -Rf foo/. bar

1
क्या ये सच है? असामान्य लगता है।
मटेंग

2
@ मटेंग मैंने इसे अभी परीक्षण किया है - हां यह सच है।
मटेरमोन

1
.निर्देशिका में सभी फ़ाइलों का मतलब है। इसलिए, स्वाभाविक रूप से छिपी हुई फ़ाइलों को शामिल किया जाएगा।
जसप्रीत सिंह

यह वास्तव में बहुत साफ है। आप लिनक्स पर "cp -RTf foo bar" भी कर सकते हैं।
xpusostomos

5

@ जोनाथन व्हीलर के समान:

यदि आप याद नहीं करना चाहते हैं, लेकिन फिर से लिखना नहीं है bar:

rm -r bar/
cp -r foo/ !$

!$ आपके पिछले आदेश के अंतिम तर्क को प्रदर्शित करता है।


4
$! के बारे में टिप बहुत बढ़िया है!
लुकास मॉर्गन

0

इससे आपकी समस्या का समाधान हो जाना चाहिए।

\cp -rf foo/* bar/

-1

आपके द्वारा निर्धारित ऑपरेशन एक "मर्ज" है और आप ऐसा नहीं कर सकते cp। हालांकि, यदि आप फ़ोल्डर को खोने के लिए विलय और ठीक नहीं देख रहे हैं, तो आप barबस rm -rf barफ़ोल्डर को हटा सकते हैं और फिर mv foo barउसका नाम बदल सकते हैं। यह किसी भी समय नहीं लेगा क्योंकि दोनों ऑपरेशन फ़ाइल पॉइंटर्स द्वारा किए जाते हैं, फ़ाइल सामग्री नहीं।


-2

दो चरणों वाले इस आदेश का उपयोग करने का प्रयास करें:

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