मैं वाइल्डकार्ड द्वारा कई फ़ाइलों की प्रतिलिपि कैसे बना सकता हूं?


42

मेरे पास एबीसी में कई फाइलों के साथ एक फ़ोल्डर है। * (लगभग 100 ऐसी फाइलें हैं)। मैं उन सभी नई फाइलों की नकल करना चाहता हूं जिनके नाम डीईएफ से शुरू होते हैं। *

इसलिए मुझे चाहिए

ABC.Page1
ABC.Page2
ABC.Topic12
...etc

की नकल की

DEF.Page1
DEF.Page2
DEF.Topic12
...etc

बैच कमांड (BASH या समान) के साथ ऐसा करने का सबसे सरल तरीका क्या है? मैं कुछ सोच रहा हूँ जिसमें sed या awk या xargs शामिल है, लेकिन मुझे सिंटैक्स का पता लगाने में कठिनाई हो रही है। मैं एक पायथन स्क्रिप्ट लिख सकता था, लेकिन मैं सोच रहा हूं कि शायद एक कमांड लाइन समाधान है जो बहुत जटिल नहीं है।


mcइस तरह के बड़े पैमाने पर नाम बदलने के लिए एक सम्मानित फ़ाइल प्रबंधक का सबसे व्यापक समर्थन है।
oakad

@oad tarकोई स्प्रिंग-चिकन नहीं है। एक उदाहरण के लिए मेरा जवाब देखें।
mikeserv

जवाबों:


41

कैसे के बारे में कुछ इस तरह से मार:

for file in ABC.*; do cp "$file" "${file/ABC/DEF}";done

आप cp कमांड के सामने इको लगाकर इसका परीक्षण कर सकते हैं:

for file in ABC.*; do echo cp "$file" "${file/ABC/DEF}";done

उत्तम। इससे भी आसान मैंने सोचा था।
ऑक्टोपस

यह ज्यादातर मामलों में काफी अच्छा होगा लेकिन इको के साथ जाँच यहाँ महत्वपूर्ण है। ऐसा कभी भी स्क्रिप्ट में न करें । अधिक जानकारी के लिए बैश नुकसान
pawel7318

@ pawel7318, आपके द्वारा दी गई लिंक, जबकि उत्कृष्ट सलाह, ऊपर दिए गए आदेश पर लागू नहीं होती है। इस कमांड के साथ मैं जो एकमात्र किनारे के मामले देख रहा हूं, वे हैं: (1) यह चेक न करें कि क्या टारगेट फाइल पहले से मौजूद है या नहीं और अगर टारगेट फाइल पहले से ही एक डायरेक्टरी के रूप में मौजूद है (जो फाइल को डायरेक्टरी में कॉपी कर लेगी , तो उसका करंट नेम बदलकर) और (2) अगर बहुत सारी फाइलें हैं तो ग्लोब विस्तार एक कमांड लाइन में फिट नहीं हो सकता है।
वाइल्डकार्ड

1
मुझे यह मिलता है: cp /usr/local/lib/libboost* /usr/local/lib/libboost*इको चेक के साथ।
टॉम ज़ातो

8

बड़ी संख्या में फ़ाइलों के साथ कुशलतापूर्वक ऐसा करने के लिए, cpप्रत्येक के लिए एक अलग प्रक्रिया शुरू करने से बचना बेहतर है । एक तरीका यह होगा कि फिर कॉपी करके उनका नाम बदला जाए prename( renameइसे डेबियन आधारित डिस्ट्रोस पर डिफ़ॉल्ट रूप से सहानुभूति दी गई है)। यह और लिनक्स का उपयोग करना mktemp:

tmp=$(mktemp -d --tmpdir=.)
cp ABC.* "$tmp"
prename "s:$tmp/ABC:DEF:" "$tmp/"*
rmdir "$tmp"

अद्यतन करें

वास्तव में paxयहां जाने का एक बेहतर तरीका हो सकता है:

pax -rws '/^ABC/DEF/' ABC.* .

दुर्भाग्य से, paxPOSIX और Linux मानक बेस दोनों होने के बावजूद , कुछ डिस्ट्रोस वर्तमान में इसे डिफ़ॉल्ट रूप से शामिल करते हैं।


भागने से बचने के लिए विभाजक के रूप में: अच्छा स्पर्श का उपयोग करना।
क्लेटन स्टेनली

5

tar यह आपके लिए वास्तव में उपवास करेगा।

परीक्षा

पहले मैंने 2 निर्देशिका और 10 फाइलें बनाई:

% mkdir test1 test2 ; cd test1
% for n in `seq 1 10` ; do touch ABC.file$n ; done
% ls

> ABC.file1   ABC.file2  ABC.file4  ABC.file6  ABC.file8
> ABC.file10  ABC.file3  ABC.file5  ABC.file7  ABC.file9

फिर मैंने उन्हें कॉपी किया:

% tar -cf - ./* |\ 
    tar -C../test2 --transform='s/ABC/DEF/' -xf -
% ls ../test2

> DEF.file1   DEF.file2  DEF.file4  DEF.file6  DEF.file8
> DEF.file10  DEF.file3  DEF.file5  DEF.file7  DEF.file9

बदलने

इसलिए GNU फ़ाइल का नाम बदलने के लिए tarस्वीकार करेगा sed --transform=EXPRESSION। यह भी केवल कुछ फ़ाइलों का नाम बदल सकता है। उदाहरण के लिए:

% tar -cf - ./* |\ 
    tar -C../test2 --transform='s/ABC\(.*[0-5]\)/DEF\1/' -xf -
% ls ../test2

> ABC.file6  ABC.file8  DEF.file1   DEF.file2  DEF.file4
> ABC.file7  ABC.file9  DEF.file10  DEF.file3  DEF.file5

तो वह एक फायदा है।

धारा

यह भी विचार करें कि यह केवल दो tarप्रक्रियाएं हैं - और यह आपकी फ़ाइल गणना की परवाह किए बिना नहीं बदलेगा।

tar | tar

tarजैसा कि आप चाहते हैं कि यह अनुकूलित हो। इससे कभी भी समस्या का तर्क मायने नहीं रखता या बच्चे की प्रक्रिया नहीं हो सकती। यह सिर्फ A> B किया गया है।

ARGUMENTS

मैं tarयहां अपनी दो प्रक्रियाओं के बीच संयुक्त 7 अलग-अलग तर्कों का उपयोग करता हूं । सबसे महत्वपूर्ण यहाँ पहले सूचीबद्ध है:

-stdout / stdin - यह सूचित करता है tarकि यह या तो इसके इनपुट या आउटपुट को स्ट्रीम कर रहा होगा या stdin/stdoutजिसमें से यह सही ढंग से व्याख्या करेगा कि यह आर्काइव का निर्माण कर रहा है या नहीं।

-ccreate - यह tarआर्काइव बनाने के लिए कहता है। अगले तर्क की tarउम्मीद है ...

-fफ़ाइल - हम निर्दिष्ट करते हैं कि टेप-डिवाइस या जो भी tarहो, एक fileवस्तु के साथ काम करना होगा । और जैसा कि ऊपर उल्लेख किया गया है, वह फाइल stdin/stdout- दूसरे शब्दों में, हमारी है |pipe

./*सभी $ पीडब्ल्यूडी / फ़ाइलें - नहीं बहुत ज्यादा, सिवाय इसके कि संग्रह तर्क, पहले आता है इसलिए यहाँ की व्याख्या करने के -तो ./*

... और दूसरी तरफ |pipe...

-Cपरिवर्तन निर्देशिका - यह बताती है tarकि किसी भी अन्य क्रिया को करने से पहले मेरे द्वारा निर्दिष्ट निर्देशिका में इसे बदलना आवश्यक है, इसलिए cd ../test2निष्कर्षण से ठीक पहले इसे प्रभावी ढंग से करें।

--transform='s/ed/EXPR/'- जैसा कि पहले ही उल्लेख किया गया है, इसने नामकरण किया। लेकिन डॉक्स संकेत करता है कि यह कोई भी sedअभिव्यक्ति ले सकता है या //flag

-xएक्स्ट्रेक्ट - tarहमारी टार्गेट डायरेक्टरी में बदलाव के बाद और हमारे रीनेमिंग निर्देशों को प्राप्त करने के बाद, हम इसे निर्देश देते हैं कि -f - |pipeआर्काइव फाइल से इसकी वर्तमान डाइरेक्टरी में सभी फाइलों को निकालना शुरू करें । कोई रहस्य नहीं।


1
paxइस प्रश्न का हल यहां प्रस्तुत है । मैं इसे अपने उत्तर में जोड़ूंगा, लेकिन मुझे लगता है कि यह यहाँ बेहतर है -pax -rws '/^ABC/DEF/' ABC.* .
ग्रीम

@ ग्रेमे - वाह - यह बेहतर तरीका है! यार, यह मोती के नाम से नरक को भी हरा देता है! आपको इसे अपने उत्तर में रखना चाहिए - paxPOSIX निर्दिष्ट है - इसलिए pax
मोकेसर

paxयह POSIX हो सकता है, लेकिन यह दुर्भाग्य से डिफ़ॉल्ट रूप से स्थापित है।
ग्रीम

4

यदि आप एक कम मानक उपकरण का उपयोग करने में कोई आपत्ति नहीं करते हैं, तो मैं mmv (मास मूव) का उपयोग करने की सलाह देता हूं जो इस तरह के कार्यों के लिए लिखा गया था। mcp(मास कॉपी) का उपयोग करना , जो सूट का हिस्सा है, आप बस कर सकते हैं

mcp "ABC.*" "DEF.#1"

डाउनलोड पैकेज खोजना बिल्कुल आसान नहीं है। घर पर संकलित करने के लिए वर्तमान डेबियन पैकेज (जो आर्क भी AUR में उपयोग करता है) यहां पाया जा सकता है


बॉक्स से बाहर 15.10 पर ubuntu पर स्थापित,apt-get install mmv
11

2

Zsh में, निम्न पंक्तियाँ अपने में रखें .zshrc:

autoload -U zmv
alias zmv='noglob zmv'
alias zcp='zmv -C'
alias zln='zmv -L'

फिर, कमांड लाइन पर, आप चला सकते हैं

zcp 'ABC(.*)' 'DEF$1'

या केवल

zcp -W ABC.* DEF.*

एक अन्य शेल में, जब तक आपने zsh स्थापित किया है:

zsh -c 'autoload zmv; noglob zmv -CW ABC.* DEF.*'

1

आप ऐसा कर सकते हैं:

for i in ABC.*; do cp {ABC,DEF}."${i#*.}"; done

हो सकता है कि कुछ ऐसा है जो मैं नहीं देख रहा हूं, लेकिन मैं कई गंतव्य कैसे सेट कर रहा हूं? मैं प्रत्येक प्राप्त करने के लिए लूप के लिए उपयोग कर रहा हूं। मैंने पहले से ही कोड का परीक्षण किया, और यह उम्मीद के मुताबिक काम किया, इसलिए मैं आपके स्पष्टीकरण की सराहना करूंगा।
सारा फौज़िया

यह मेरा बुरा है, मैंने आपके जवाब को गलत बताया। :-)
क्रिस डाउन

मुझे "${i#*.}"बिट कैसे पढ़ना चाहिए ?
dumbledad

-1

आप ऐसा कर सकते हैं: http://www.projectik.eu/index.php/programovanie/linux/item/243-linux-kopirovanie-suborov-vo-vlakne यहाँ उदाहरण है


1
यूनिक्स और लिनक्स में आपका स्वागत है! हालांकि यह सैद्धांतिक रूप से प्रश्न का उत्तर दे सकता है, लेकिन उत्तर के आवश्यक भागों को यहां शामिल करना बेहतर होगा , और संदर्भ के लिए लिंक प्रदान करें।
terdon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.