Gnu cp कमांड का उपयोग करके कई डायरेक्टरी में फाइल कॉपी कैसे करें


210

क्या cp कमांड का उपयोग करके एक ही फाइल को कई डायरेक्टरी में कॉपी करना संभव है?

मैंने निम्नलिखित कोशिश की, जो काम नहीं किया:

cp file1 /foo/ /bar/
cp file1 {/foo/,/bar}

मुझे पता है कि यह लूप के लिए संभव है, या खोज। लेकिन क्या ग्नू cp कमांड का उपयोग करना संभव है?

जवाबों:


106

नहीं, cpकई स्रोतों को कॉपी कर सकते हैं लेकिन केवल एक ही गंतव्य पर कॉपी करेंगे। आपको cpकई बार - एक बार गंतव्य के लिए - आप क्या करना चाहते हैं, इसके लिए व्यवस्था करने की आवश्यकता है; का उपयोग करते हुए, जैसा कि आप कहते हैं, एक लूप या कुछ अन्य उपकरण।


जवाब के लिए धन्यवाद! अब जब मैं इसके बारे में थोड़ा और सोचता हूं, बिना अतिरिक्त झंडे के (जो मौजूद नहीं है) cp को नहीं पता होगा कि स्रोत क्या है और DEST dir क्या है।
टॉम फीजन

10
यह सही उत्तर नहीं है। कृपया रॉबर्ट गैम्बल का जवाब देखें।
प्लेग हैमर 21

23
@ नोक्टर्न: मैंने जो कहा वह गलत है? रॉबर्ट एक और उपकरण का उपयोग करने का उदाहरण देता है जैसा कि मैंने सुझाव दिया है कि कई बार सीपीपी को लागू करने के लिए। ऐसा करने के लिए अन्य उपकरणों या निर्माणों का उपयोग करने वाले कई संभावित समाधान हैं, लेकिन ओपी ने संकेत दिया कि वह पहले से ही जानता था कि यह संभव है।
चंद्रमा

2
दुख की बात है कि यह उस सुविधा का समर्थन करने के लिए cp (और scp) के लिए बहुत अच्छा होगा। फिर भी हम विभाजन करने के लिए टी का उपयोग कर सकते हैं। superuser.com/questions/32630/…
साइमन

4
@moonshadow: बेशक आपका जवाब सही है। मुझे लगता है कि प्लेगहैमर यह कहना चाहता है कि इस संदर्भ में अन्य उत्तर अधिक उपयोगी है। शायद आप भी अपने जवाब में ऐसा कुछ शामिल कर सकते हैं?
शांतिपूर्ण

585

आप इसे cpअकेले नहीं कर सकते, लेकिन आप इसके cpसाथ जोड़ सकते हैं xargs:

echo dir1 dir2 dir3 | xargs -n 1 cp file1

कॉपी करेंगे file1करने के लिए dir1, dir2और dir3। ऐसा करने के लिए 3 बार xargsकॉल करेंगे cp, xargsविवरण के लिए मैन पेज देखें।


3
Xargs पर अधिक जानकारी: cyberciti.biz/faq/…
क्रिस बिएर

24
@ साइमन ऐसा कैसे? "आप इसे cpअकेले नहीं कर सकते हैं" सिर्फ इसलिए कि दूसरे तरीके का सुझाव देकर मददगार बनने का प्रयास किया गया है इसका मतलब यह नहीं है कि प्रश्न का उत्तर नहीं दिया गया था।
निकोल

3
@NickC निर्धारक ने निर्दिष्ट किया: "मुझे पता है कि यह लूप के लिए उपयोग करना संभव है, या खोज। लेकिन क्या ग्नू cp कमांड का उपयोग करना संभव है?" अच्छा उत्तर वह है जिसे स्वीकार किया गया है।
साइमन

25
उस उत्तर को निर्धारित करना, जिसके आधार पर स्वीकार किया जाता है कि वे तकनीकी रूप से इस प्रश्न का उत्तर देते हैं कि यह अनिवार्य रूप से पांडित्य है और वास्तव में उपयोगी नहीं है।
बैकगैमौन

4
बहुत मददगार! मेरे जैसे अन्य शुरुआती लोगों के लिए: आप cp के साथ regex का उपयोग नहीं कर सकते, लेकिन आप इस आदेश के पहले भाग में कर सकते हैं (जैसे echo dir[1-3] | xargs -n 1 cp filename)।
जेसन

77

वाइल्डकार्ड भी रॉबर्ट्स कोड के साथ काम करते हैं

echo ./fs*/* | xargs -n 1 cp test 

और पूरी टिप्पणी ... उदाहरण के लिए, एक रूट-स्वामित्व वाली फ़ाइल (वास्तव में एक सिमलिंक) को स्थानांतरित करने के लिए, जो कि मेरे डेस्कटॉप पर सभी उपयोगकर्ताओं के डेस्कटॉप पर थी, मुझे सबसे पहले सू सू करना था (अन्यथा काम नहीं किया गया) फिर इस्तेमाल किया: इको / होम / * / डेस्कटॉप / | xargs -n 1 cp -av / home / myusername / Desktop / file।
डेविड जी

19

जहाँ तक मैं इसे देख सकता हूँ आप निम्नलिखित का उपयोग कर सकते हैं:

ls | xargs -n 1 cp -i file.dat

-iका विकल्प cpआदेश का मतलब है आप के साथ वर्तमान निर्देशिका में एक फ़ाइल को अधिलेखित करने के लिए है कि क्या कहा जाएगा कि file.dat। हालांकि यह पूरी तरह से स्वचालित समाधान नहीं है, लेकिन यह मेरे लिए काम करता है।


1
हालांकि -iगार्ड को जोड़ना अच्छा है , क्या यह आपको हर फ़ाइल लिखने के बारे में संकेत नहीं देगा? निर्देशिकाओं की नकल करने के बजाय?
हेजहोग

1
@ हेजल वेल, मुझे लगता है कि यह कमांड उपयोगी है जब निर्देशिका में एक फ़ाइल होती है और कोई इसे निर्देशिका की उपनिर्देशिकाओं पर कॉपी करना चाहता है। इस मामले में एक फ़ाइल को केवल एक बार ही अधिलेखित किया जा सकता है। आपके प्रश्न के लिए धन्यवाद!
एवगेनी

2
मेरे लिए, इसने cp: overwriteसवालों की एक श्रृंखला छापी , लेकिन मुझे उनमें से किसी का भी जवाब नहीं देना पड़ा, और इसने फाइलों को अधिलेखित नहीं किया।
इवगेनी सर्गेव

इसके अलावा प्रश्नों की एक श्रृंखला छपी + के साथ dir के नाम के साथ फाइल करने के लिए कॉपी किया गया: 'चरित्र अंत में, कोई काम नहीं कर रहा समाधान, पॉल समाधान पूरी तरह से काम कर रहा है
jgpATs2w

19

मैं का प्रयोग करेंगे catऔर teeजवाब मैं में देखा था के आधार पर /superuser/32630/parallel-file-copy-from-single-source-to-multiple-targets के बजाय cp

उदाहरण के लिए:

cat inputfile | tee outfile1 outfile2 > /dev/null

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

1
यदि आप bash 3.0 या उच्चतर का उपयोग कर रहे हैं, तो आप निम्नानुसार श्रेणियों का उपयोग कर सकते हैं:cat <inputfile> | tee /path-to-files/outfile{1..4} > /dev/null
Samuel

tee < inputfile outfile1 outfile2 > /dev/nullयह भी एक उपयोगी पैटर्न है जैसा कि टेवे के उत्तर द्वारा दिखाया गया है। Io <-redirection के उपयोग को '<' के साथ नोट करें ताकि बिल्ली से पाइपिंग की आवश्यकता न हो।
एलेक्स टेलॉन

10

ये उत्तर सभी स्पष्ट से अधिक जटिल लगते हैं:

for i in /foo /bar; do cp "$file1" "$i"; done

एक सुंदर और काम कर, वर्तमान निर्देशिका में सभी निर्देशिकाओं के लिए, एक का उपयोग कर सकते हैंfor d in */ ; do cp $file "$i" done
FantomX1

9

ls -db di*/subdir | xargs -n 1 cp File

-bअगर निर्देशिका नाम में कोई स्थान है तो इसे xargs द्वारा एक अलग आइटम के रूप में तोड़ा जाएगा, यह समस्या गूंज संस्करण के साथ थी


6

प्रति sep का उपयोग नहीं कर रहा है, लेकिन ...

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

$ tar cf - src | tee >( cd dest1 ; tar xf - ) >( cd dest2 ; tar xf - ) | ( cd dest3 ; tar xf - )

(और यदि आप अधिक आउटपुट चाहते हैं तो आप उनमे से>> () अनुभाग जोड़ सकते हैं।)

मैंने ऐसा नहीं माना है, लेकिन यह निश्चित रूप से cp-in-a-loop (या समानांतर cp इनवोकेशन का एक गुच्छा) की तुलना में बहुत तेज़ है।


5

xargsमैक ओएस पर वाइल्डकार्ड्स का उपयोग करके निर्देशिकाओं के साथ प्रतिलिपि बनाने के लिए, एकमात्र समाधान जो मेरे लिए निर्देशिका नाम के रिक्त स्थान के साथ काम करता है वह है:

find ./fs*/* -type d -print0 | xargs -0 -n 1 cp test 

testकॉपी करने के लिए फाइल कहां है
और ./fs*/*निर्देशिका को कॉपी करने के लिए

समस्या यह है कि xargs रिक्त स्थान को एक नए तर्क के रूप में देखता है, उपयोग करने वाले सीमांकक चरित्र को बदलने का समाधान -dया -Eदुर्भाग्य से मैक ओएस पर ठीक से काम नहीं कर रहा है।


4

अगर आप इसे बिना फोर्क्ड कमांड के करना चाहते हैं:

tee <inputfile file2 file3 file4 ... >/dev/null


2

मूल रूप से xargs उत्तर के बराबर है, लेकिन यदि आप समानांतर निष्पादन चाहते हैं:

parallel -q cp file1 ::: /foo/ /bar/

इसलिए, उदाहरण के लिए, मौजूदा फ़ोल्डर के सभी उपनिर्देशिकाओं में फ़ाइल 1 को कॉपी करने के लिए (पुनरावृत्ति सहित):

parallel -q cp file1 ::: `find -mindepth 1 -type d`

नायब: यह शायद केवल बहुत विशिष्ट उपयोग के मामलों के लिए कोई ध्यान देने योग्य गति लाभ देता है, जैसे कि यदि प्रत्येक लक्ष्य निर्देशिका एक अलग डिस्क है।

यह कार्यात्मक रूप से xargs के '-P' तर्क के समान है।


0

नहीं तुम नहीं कर सकते।

मैंने कई अवसरों पर पाया है कि मैं इस कार्यक्षमता का उपयोग कर सकता हूं इसलिए मैंने अपने लिए यह करने के लिए अपना उपकरण बनाया है।

http://github.com/ddavison/branch

बहुत साधारण -
branch myfile dir1 dir2 dir3


अक्सर ऐसे परिदृश्य होते हैं जहां मैं अपनी खुद की ऐसी स्क्रिप्ट लिखूंगा, लेकिन मैं आजकल बहुत सारी मशीनों का उपयोग करता हूं कि इन सभी को सिंक में रखना एक बड़ी परेशानी की तरह लगता है। यदि केवल /eउदाहरण के लिए क्लाउड वेब निर्देशिका को माउंट करने का एक तरीका था , बस प्रत्येक मशीन पर एक बार, तो मैं अपने खुद के पावरटूल लिख सकता था और उन्हें हमेशा के लिए रख सकता था।
इवगेनी सर्गेव

0
ls -d */ | xargs -iA cp file.txt A

1
थोड़ा स्पष्टीकरण के बारे में कैसे?
मिनट

यह वास्तव में काम करता है, लेकिन एक स्पष्टीकरण महान होगा
31lex

0

मान लीजिए कि आप fileName.txtसभी उप-निर्देशिकाओं को वर्तमान कार्यशील निर्देशिका में कॉपी करना चाहते हैं ।

  1. सभी उप-निर्देशिका नाम प्राप्त करें lsऔर उन्हें कुछ अस्थायी फ़ाइल में सहेजें,allFolders.txt

    ls > allFolders.txt
  2. सूची को प्रिंट करें और इसे कमांड को पास करें xargs

    cat allFolders.txt | xargs -n 1 cp fileName.txt

0

एक अन्य तरीका बिल्ली और टी का उपयोग इस प्रकार है:

cat <source file> | tee <destination file 1> | tee <destination file 2> [...] > <last destination file>

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


0

एक बैश स्क्रिप्ट का उपयोग करना

DESTINATIONPATH[0]="xxx/yyy"
DESTINATIONPATH[1]="aaa/bbb"
                ..
DESTINATIONPATH[5]="MainLine/USER"
NumberOfDestinations=6

for (( i=0; i<NumberOfDestinations; i++))
    do
        cp  SourcePath/fileName.ext ${DESTINATIONPATH[$i]}

    done
exit

मैंने इस बात को खारिज कर दिया। प्रश्न विशेष रूप से एक गैर-लूप समाधान के लिए पूछा गया था।
एलेक्स टेलॉन

-1

यदि आप कई फ़ोल्डरों को एक से अधिक फ़ोल्डर में कॉपी करना चाहते हैं, तो ऐसा कुछ कर सकते हैं:

गूंज dir1 dir2 dir3 | xargs -n 1 cp -r / path / Toyourdir / {subdir1, subdir2, subdir3}


-1

यदि आपके सभी लक्ष्य निर्देशिका पथ अभिव्यक्ति से मेल खाते हैं - जैसे कि वे सभी उपनिर्देशिकाएँ हैं path/to- तो बस इस तरह से findसंयोजन में उपयोग cpकरें:

find ./path/to/* -type d -exec cp [file name] {} \;

बस।


मैंने इस बात को खारिज कर दिया। प्रश्न विशेष रूप से एक गैर-खोज समाधान के लिए पूछा गया।
एलेक्स टेलॉन

इतनी अच्छी तरह से @AlexTelon होने के लिए धन्यवाद। मुझे लगता है मैं उस बिट को याद किया। मुझे आशा है कि आप भी सुसंगत थे और findथ्रेड का उपयोग करके हर दूसरे उत्तर के लिए एक डाउन-वोट दिया ।
मिग 82

-2

यदि आपको उस फ़ोल्डर में विशिष्ट होने की आवश्यकता है जिस फ़ाइल को आप एक या एक से अधिक greps के साथ जोड़ सकते हैं। उदाहरण के लिए किसी भी सबफ़ोल्डर में favicon.ico की किसी भी घटना को बदलने के लिए जिसका आप उपयोग कर सकते हैं:

find . | grep favicon\.ico | xargs -n 1 cp -f /root/favicon.ico

-3

यह तत्काल उप-निर्देशिकाओं की नकल करेगा, यदि आप गहराई से जाना चाहते हैं, तो -maxdepthपैरामीटर समायोजित करें ।

find . -mindepth 1 -maxdepth 1 -type d| xargs -n 1 cp -i index.html

यदि आप सभी निर्देशिकाओं को कॉपी नहीं करना चाहते हैं, तो उम्मीद है कि आप उन निर्देशिकाओं को फ़िल्टर कर सकते हैं जिनमें आप रुचि नहीं रखते हैं। उदाहरण के लिए सभी फ़ोल्डरों को कॉपी करना शुरू होता है। a

find . -mindepth 1 -maxdepth 1 -type d| grep \/a |xargs -n 1 cp -i index.html

यदि आप निर्देशिका के एक मनमाने ढंग से / निराशाजनक सेट की नकल करते हैं तो आपको रॉबर्ट गैम्बल के सुझाव की आवश्यकता होगी।


-3

मैं एक फाइल को कई निर्देशिकाओं में कॉपी करना पसंद करता हूं: cp file1 /foo/; cp file1 /bar/; cp file1 /foo2/; cp file1 /bar2/ और एक निर्देशिका को अन्य निर्देशिकाओं में कॉपी करना: cp -r dir1/ /foo/; cp -r dir1/ /bar/; cp -r dir1/ /foo2/; cp -r dir1/ /bar2/

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


7
आप 6 साल पुराने प्रश्न का उत्तर 15 अन्य उत्तरों के साथ दे रहे हैं। आपके उत्तर के लिए सुंदर उपन्यास होना चाहिए। मेरी राय - यह नहीं है।
क्रेग एस। एंडरसन

-4

उदाहरण के लिए यदि आप अपने गंतव्य फ़ोल्डर की मूल निर्देशिका में हैं, तो आप कर सकते हैं:

i में $ (ls) के लिए; cp sourcefile $ i; किया हुआ


प्रश्न कहता है कि यह लूप के लिए संभव है, इसलिए यह वास्तव में कुछ भी नहीं जोड़ता है।
LJNielsenDk

Downvoted। कभी भी आउटपुट को पार्स करने का प्रयास न करेंls , और हमेशा चर का उद्धरण करें। for i in ./*; do cp sourcefile "$i"; done
स्लीपब्लैंक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.