लिनक्स: dir और subdirs से मेल खाने वाले सभी फाइल को एक ही dir में कॉपी करें


31

अगर मैं सभी की नकल करना चाहता था *.soसे फाइल srcकरने के लिए dstमुझे क्या करना चाहते हैं:

cp src/*.so dst

हालाँकि, मैं सभी *.soफाइलों को src से कॉपी करना चाहता हूँ और यह उप-विभाजनों में है dst। कोई सुराग?

जवाबों:


36

प्रयत्न:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

17
findपैटर्न मिलान और कमांड निष्पादित कर सकते हैं। पाइप के लिए कोई ज़रूरत नहीं है इसके उत्पादन:find src/ -type f -name '*.so' -exec cp '{}' dst/ ';'
jáquer

1
हाँ, यह एक पाइपलाइन पढ़ना अक्सर आसान हो सकता है, यह भी पैरामीटर के लिए grepउपयोग किए जाने वाले सरल शेल पैटर्न को दूर करने की पैटर्न मिलान क्षमता -nameहै find। पैरामीटर xargsसे भी अधिक शक्तिशाली है । -execfind
माइक इंशाल

2
@ विजयर का समाधान बहुत बेहतर है क्योंकि MacOSX xargs उपयोगिता पर -i विकल्प नहीं है। लेकिन उसका समाधान एक आकर्षण की तरह काम करता है।
bialix

मैं jar के समाधान के संबंध में @bialix की टिप्पणी को पढ़ने तक xargs के -i तर्क पर एक त्रुटि संदेश के साथ संघर्ष कर रहा था, जिसने मेरे मैक पर पूरी तरह से काम किया। धन्यवाद
svannoy

क्या यह आवश्यकतानुसार उपनिर्देशिकाएँ बनाएगा?
लेनार्ट रोलैंड

15

यदि आप बैश का उपयोग कर रहे हैं, तो आप फ़ाइलों और निर्देशिकाओं का मिलान globstar करने के लिए शेल विकल्प को चालू कर सकते हैं :

shopt -s globstar
cp src/**/*.so dst

यदि आपको उन फ़ाइलों को खोजने की आवश्यकता है जिनके नाम के साथ शुरू होता है ., और / या निर्देशिका में और जिनके नाम के साथ फाइलें शुरू होती हैं ., तो dotglobविकल्प भी सेट करें (जैसे, साथ shopt -s dotglob)। आप उन दोनों को एक कमांड में सेट कर सकते हैं:

shopt -s globstar dotglob

के साथ शुरू होने वाली उपनिर्देशिकाओं में फाइलों की नकल नहीं करता है। उनके नाम पर
राजदूत

8

मैंने माइक द्वारा सुझाए गए आदेश की कोशिश की:

find src/ -type f | grep -i so$ | xargs -i cp {} dst

लेकिन यह सभी फाइलों को निर्देशिका में डंप करने के साथ समाप्त हो गया, dstक्योंकि उनके सापेक्ष पथ खो गए थे।

रिश्तेदार रास्तों को रखने के लिए कमांड को इसे संशोधित करने की आवश्यकता है:

find src/ -type f | grep -i so$ | xargs -i cp {} dst/{}

7
+1। हालाँकि, यह मानता है कि संबंधित स्रोत पथ के अनुरूप निर्देशिकाएँ मौजूद हैं dst। मामले में ऐसा नहीं है, का उपयोग करें cp --parents। इसके अलावा, फ़ाइलनाम को उद्धृत करना सुनिश्चित करें। इस प्रकार: ... | xargs -i cp --parents "{}" dst(ध्यान दें कि अंतिम तर्क cpअब "बस" गंतव्य निर्देशिका है)। -tध्वज का उपयोग करके कमांड को और भी छोटा (और शायद तेज) किया जा सकता है ... | xargs cp --parents -t dst:।
Stephan202

1
@ Stephan202 का मुझे इस्तेमाल करना था... | xargs cp {} --parents -t dst.
warvariuc

एक मैक पर उन लोगों के लिए, --parentsउपलब्ध नहीं है। मैंने dittoइसके स्थान पर उपयोग किया : stackoverflow.com/questions/11246070/cp-parents-option-on-mac
ब्रायन यंग

3

इसे करने का एक और तरीका इस प्रकार है:

find src/ -type f -name "*.so" -exec cp {} dst/ \;

और यह की संख्या को कम करना चाहिए cpप्रक्रियाओं: ... -exec cp -t dst/ {} +
कामिल मैकियोरोस्की

हे कामिल! टिप्पणी के लिए धन्यवाद! क्या आप कृपया मुझे समझा सकते हैं कि कैसे आपका समाधान चीजों को तेज करता है! हमेशा अधिक जानने के लिए तैयार :)
Kyriakos

जब आप समाप्त -execकरते हैं ;, {}तो एक समय में एक पथ द्वारा प्रतिस्थापित किया जाता है। आपको cpहर फ़ाइल के लिए एक अलग मिलता है । साथ +वाक्य रचना findकी जगह {}एक से अधिक परिणाम के साथ (कमांड लाइन लंबाई की एक प्रणाली द्वारा परिभाषित सीमा तक; प्रतिबंध: {}से पहले आखिरी बात होना चाहिए +, इसलिए cp -t)। किसी प्रक्रिया को बनाना और समाप्त करना अपेक्षाकृत महंगी बात है। इस कारण से +जब भी आप बहुत सारे परिणामों की अपेक्षा करते हैं तो इसका उपयोग करना अच्छा होता है। इस मामले में बहुत सारी फाइलें कॉपी करने में काफी समय लग सकता है, इसलिए यह अंतर किसी का ध्यान नहीं जा सकता है; फिर भी यह एक अच्छा अभ्यास है।
कामिल मैकियोरोस्की

1

Grep को find -name के उपयोग से बदला जा सकता है :

find src/ -type f -name "*.so" | xargs -i cp {} dst/{}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.