2013-07-05 4 views
11

ネットワークフォルダ\\server\source(すべてのネストされたフォルダ内のファイルを含む)からローカルフォルダC:\destinationへすべてのファイル(ただし、名前が*.docに一致するフォルダではない)をすべてコピーする必要があります。 C:\destinationであり、ネストされたフォルダはC:\destinationには作成されません)。 \\server\sourceの異なるサブフォルダから同じ名前のファイルが複数ある場合は、最初のファイルのみコピーして上書きしないでください。後で見つかる競合するファイルはすべてスキップする必要があります(スキップしたファイルは、ネットワーク上で転送する必要があります。それ以外の場合は、時間がかかります)。ここではPowerShellでそれを実装する私の試みは次のとおりです。名前があまりにも*.docと一致特定のファイルをコピーするには(フォルダ階層なし)、既存のファイルを上書きしないでください。

  • それをコピーするフォルダ:このコマンドを使用して、少なくとも二つの問題があります

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

  • 競合する名前の場合、後で見つかったファイルはネットワーク経由で転送され、前のファイルを上書きします。

これらの問題を解決する方法を提案できますか?
copy,xcopy,robocopy,cscriptまたは*.bat,*.cmdの実装も歓迎します。
ローカルOSはWindows 8で、ファイルシステムはNTFSです。

+0

スクリプトが2回実行されると、どのような動作が期待できますか?一度すべてをコピーする必要がありますか?それとも何もコピーしないのですか? –

+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) 
    }; 
} 

、ディレクトリを取り除くためにwhere-objectを通じてパイプ、フィルタに一致するソースフォルダ内のファイルを一覧表示するGet-ChildItemを使用します。このような

何か。

そしてforeachループ内の各ファイルを通って移動し、ファイル名が(フルネームではない)system.io.file .NETクラスのExists方法を用いて、先に存在するかどうかを確認します。

元のファイル名だけを使用してコピーします(元のパスを削除する)。

テストするとき、それは唯一のケース結果には、それはどうなるのか表示して、コピーの-whatifオプションを使用しますが、あなたが:-)

+1

あなたが逃している括弧 –

+0

'[システム.io.file] :: Exists'の代わりに' Test-File'も使用できるはずです – 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ファイルと* .doc? (したがって、Office 2010の.docx形式も考慮します)、ディレクトリと重複ファイルは除きます。
2行目は、各アイテムを宛先からソースにコピーします(フォルダC:\ destinationはすでに存在している必要があります)。
一般的には、複数の行にコマンドを分割することをお勧めします。コードを生成する方が簡単です(この場合は最初のタスク:ファイルの取得、2番目のタスク:ファイルのコピー)。

6

私が何かを誤解していない限り、以前の回答は私にはやや複雑すぎるようです。コピー、XCOPY、またはrobocopyを - - あなたが自分でやりたいんでしょうが、http://www.xxcopy.comで便利な利用できるという意志xxcopyと呼ばれるユーティリティは、あります組み込みコマンドの

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

なし:これは動作するはずです。ディレクトリツリーを単一のディレクトリにまとめるための組み込みオプションが数多く用意されています。以下は、あなたが説明したものを行います。

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

をしかし、xxcopyは、このようなファイル名にソースディレクトリ名を追加、またはシーケンシャル数値識別を追加するなど、ちょうど遭遇した最初のものをコピーするよりも、重複するファイル名を処理するための様々な他のオプションを持っています最初のものを除くすべてのもの、または最新のものと古いものを除くすべてのものに適用されます。詳細についてはこのページを参照してください。http://www.xxcopy.com/xxcopy16.htm

+0

Hmmm、私は本当にこのdownvoteを理解していません。最初の行のフレーズ。それは侮辱を意図したものではなく、すでに投稿された回答がより簡単にできる何かのための余計なステップを経ていると感じました。明快さを犠牲にしない限り、単純化と簡潔さはコーディングでは好ましいと思われますか?とにかく、OPは、具体的には、彼はコピーコマンドを使用してソリューションを歓迎すると述べた。私は、彼が単一のスイッチで達成したいことを正確に行うために調整されたサードパーティのコピーユーティリティに関する情報を提供しました。それはどうして "役に立たない"のですか? –

+0

あなたのオプション(最初のもの)を試してみました - それは良いですが、それは階層を平らにします – Archeg

+2

階層をフラット化することは質問の目標でした: "入れ子のフォルダ階層を保存せずに(つまりすべてのファイルはC:ネストされたフォルダはC:\ destinationに作成する必要があります)。 " –

1

パイプラインを既に持っているときにforeachを使用するのはなぜですか?勝利の計算されたプロパティ!

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 
関連する問題