2013-07-05 5 views
11

मुझे सभी *.doc फ़ाइलों को कॉपी करने की आवश्यकता है (लेकिन फ़ोल्डर नहीं जिनके नाम *.doc से मेल खाते हैं) नेटवर्क फ़ोल्डर \\server\source (सभी नेस्टेड फ़ोल्डरों में फ़ाइलों सहित) को स्थानीय फ़ोल्डर C:\destination पर नेस्टेड फ़ोल्डर्स पदानुक्रम को संरक्षित किए बिना (यानी सभी फ़ाइलों को सीधे जाना चाहिए C:\destination और C:\destination में कोई नेस्टेड फ़ोल्डर्स नहीं बनाया जाना चाहिए)। यदि \\server\source के विभिन्न उपफोल्डरों से समान नाम वाली कई फाइलें हैं, तो केवल पहले को कॉपी किया जाना चाहिए और फिर कभी ओवरराइट नहीं किया जाना चाहिए - बाद में मिलने वाली सभी विवादित फ़ाइलों को छोड़ दिया जाना चाहिए (इस तरह के कई मामले हो सकते हैं, और छोड़ी गई फ़ाइलों को नेटवर्क पर trasferred नहीं है, अन्यथा इसमें बहुत अधिक समय लगेगा)। यहाँ PowerShell में इसे लागू करने के लिए अपने प्रयास है:कुछ फ़ाइलों की प्रतिलिपि कैसे करें (w/o फ़ोल्डर पदानुक्रम), लेकिन मौजूदा फ़ाइलों को ओवरराइट नहीं करते हैं?

cp \\server\source\* -Recurse -Include *.doc -Container:$false -Destination C:\destination 

इस आदेश के साथ कम से कम दो समस्याएं हैं:

  • यह प्रतियां फ़ोल्डरों जिनके नाम भी *.doc मेल खाते हैं।
  • विरोधाभासी नामों के मामले में बाद में मिली किसी भी फ़ाइल को नेटवर्क पर स्थानांतरित कर दिया गया है और पिछले एक को ओवरराइट किया गया है।

क्या आप सुझाव दे सकते हैं कि इन समस्याओं को कैसे ठीक किया जाए?
copy, xcopy, robocopy, cscript या *.bat, *.cmd का उपयोग करके कार्यान्वयन का भी स्वागत है।
स्थानीय ओएस विंडोज 8 और फ़ाइल सिस्टम एनटीएफएस है।

+0

स्क्रिप्ट दो बार चलने पर अपेक्षित व्यवहार क्या है? क्या यह अभी भी सब कुछ एक बार कॉपी करना चाहिए? या यह कुछ भी कॉपी नहीं करना चाहिए? –

+1

@splatteredbits गंतव्य निर्देशिका को प्रारंभ में खाली माना जा सकता है। यदि यह पूर्व शर्त विफल हो जाती है तो स्क्रिप्ट व्यवहार को अपरिभाषित किया जा सकता है। –

उत्तर

14

मैं पहले फाइलों की सूची तैयार करता हूं और सूची के माध्यम से सत्यापित करता हूं।

कुछ इस तरह:

$srcdir = "\\server\source\"; 
$destdir = "C:\destination\"; 
$files = (Get-ChildItem $SrcDir -recurse -filter *.doc | where-object {-not ($_.PSIsContainer)}); 
$files|foreach($_){ 
    if (!([system.io.file]::Exists($destdir+$_.name))){ 
       cp $_.Fullname ($destdir+$_.name) 
    }; 
} 

तो, Get-ChildItem का उपयोग where-object के माध्यम से फिल्टर, पाइप मिलान स्रोत फ़ोल्डर में फ़ाइलें सूची निर्देशिका बाहर पट्टी।

फिर एक foreach पाश में प्रत्येक फ़ाइल के माध्यम से जाना और देखें कि क्या फ़ाइल नाम (नहीं पूरा नाम) गंतव्य में मौजूद है system.io.file नेट वर्ग के Exists पद्धति का उपयोग करके।

यदि यह नहीं है, तो केवल मूल फ़ाइल नाम (मूल पथ छोड़ना) का उपयोग करके कॉपी करें।

उपयोग प्रति पर -whatif विकल्प, जब परीक्षण तो यह केवल प्रदर्शित करता है यह क्या करेंगे मामले परिणाम में, आप क्या :-) चाहता था

+1

आपको 'system.io.file] :: Exists' के बजाय ब्रैकेट –

+0

याद किया गया है, आपको' टेस्ट-फाइल ' – jessehouwing

2
# Get all *.doc files under \\server\source 
Get-ChildItem -Path \\server\source *.doc -Recurse | 
    # Filter out directores 
    Where-Object { -not $_.PsIsContainer } | 
    # Add property for destination 
    Add-Member ScriptProperty -Name Destination -Value { Join-Path 'C:\destination' $this.Name } -PassThru | 
    # Filter out files that exist on the destination 
    Where-Object { -not (Test-Path -Path $_.Destination -PathType Leaf } | 
    # Copy. 
    Copy-Item 
0
$docFiles = Get-ChildItem -Path "\\server\source" -Recurse | Where-Object {$_.Attributes.ToString() -notlike "*Directory*" -and ($_.Name -like "*.doc" -or $_.Name -like "*.doc?")} | Sort-Object -Unique; 
$docFiles | ForEach-Object { Copy-Item -Path $_.fullname -Destination "C:\destination" }; 

पहली पंक्ति प्रत्येक पढ़ा * नहीं है। डॉक्टर फ़ाइल और * .doc? (इसलिए यह Office 2010 .docx प्रारूप भी मानता है), निर्देशिकाओं और डुप्लिकेट फ़ाइलों को छोड़कर।
दूसरी पंक्ति गंतव्य से स्रोत तक प्रत्येक आइटम की प्रतिलिपि बनाएँ (फ़ोल्डर सी: \ गंतव्य पहले से मौजूद होना चाहिए)।
सामान्य रूप से मैं आपको कई लाइनों पर कमांड को विभाजित करने का सुझाव देता हूं क्योंकि कोड उत्पन्न करना आसान है (इस मामले में पहला कार्य: फ़ाइलें प्राप्त करें, दूसरा कार्य: प्रतिलिपि फ़ाइलें)।

6

पिछले उत्तर मुझे अपेक्षाकृत अधिक प्रतीत होते हैं, जब तक कि मैं कुछ गलत समझ नहीं पा रहा हूं। यह काम करना चाहिए:

Get-ChildItem "\\server\source\" *.doc -Recurse | ?{-not ($_.PSIsContainer -or (Test-Path "C:\Destination\$_"))} | Copy-Item -Destination "C:\Destination" 

निर्मित आदेशों में से कोई भी - प्रतिलिपि, xcopy, या robocopy - क्या आप अपने दम पर करना चाहते हैं जाएगा, लेकिन वहाँ एक उपयोगिता है कि इच्छा xxcopy कहा जाता है, http://www.xxcopy.com पर आसानी से उपलब्ध है। इसमें कई अंतर्निहित विकल्प हैं, विशेष रूप से एक निर्देशिका में निर्देशिका पेड़ को फ़्लैट करने के लिए। निम्नलिखित आप क्या वर्णित करना होगा:

xxcopy "\\server\source\*.doc" "C:\Destination" /SGFO 

हालांकि, इस तरह के xxcopy फ़ाइल नाम के स्रोत निर्देशिका का नाम जोड़ने, या जोड़ने अनुक्रमिक संख्यात्मक पहचान करता है के रूप में सिर्फ पहले एक का सामना करना पड़ा प्रति बनाने की बजाय डुप्लिकेट फ़ाइल नाम, से निपटने के लिए विभिन्न अन्य विकल्प हैं सभी के लिए सबसे पहले, या सभी नवीनतम या सबसे पुराने के लिए। विवरण के लिए यह पृष्ठ देखें: http://www.xxcopy.com/xxcopy16.htm

+0

हम्म का उपयोग करने में भी सक्षम होना चाहिए, मैं वास्तव में इस डाउनवोट को नहीं समझता, जब तक कि किसी ने अपवाद नहीं लिया पहली पंक्ति का वाक्यांश। यह अपमान के रूप में नहीं था, मुझे लगा कि पहले से ही पोस्ट किए गए उत्तरों को कुछ और कदमों के लिए अतिरिक्त कदमों से गुज़रना पड़ रहा था। जब तक आप स्पष्टता का त्याग नहीं करते हैं तब तक सादगी और सुसंगतता को कोडिंग में बेहतर माना जाता है? वैसे भी, ओपी ने विशेष रूप से कहा कि वह प्रतिलिपि आदेशों का उपयोग करके समाधान का स्वागत करेगा। मैंने एक तृतीय पक्ष प्रति उपयोगिता के बारे में जानकारी प्रदान की जो कि एक ही स्विच के साथ वह पूरा करने के लिए तैयार है। वह "उपयोगी नहीं" कैसे है? –

+0

अपना विकल्प (पहला वाला) का प्रयास किया - यह अच्छा है, लेकिन यह पदानुक्रम – Archeg

+2

पट्टियों को फ़्लैटन करना पदानुक्रम को फ़्लैट करना प्रश्न का लक्ष्य था: "नेस्टेड फ़ोल्डर्स पदानुक्रम को संरक्षित किए बिना (यानी सभी फाइलों को सी: \ गंतव्य और सीधे में जाना चाहिए नेस्टेड फ़ोल्डरों को सी: \ गंतव्य में बनाया जाना चाहिए) "। –

1

आपके पास पहले से ही पाइपलाइन होने पर फ़ोरैच का उपयोग क्यों करें? जीत के लिए परिकलित गुण!

Get-ChildItem -Recurse -Path:\\Server\Path -filter:'*.doc' | 
    Where { -not $_.PSIsContainer } | 
    Group Name | 
    Select @{Name='Path'; Expression={$_.Group[0].FullName}},@{Name='Destination'; Expression={'C:\Destination\{0}' -f $_.Name}} | 
    Copy-Item 
संबंधित मुद्दे

 संबंधित मुद्दे