既存のファイルを上書きしない方法

既存のファイルを上書きしない方法

現在、私はコピーアイテム存在しないファイルや日付/時刻で新しいファイルのみをコピーする簡単なコマンドがあるかどうか疑問に思っています。オンラインで調べたのですが、私が見たものはすべて-もしもコマンド。また、-再帰使用されています。そのコマンドが何をするのかもよくわかりません。何かアイデアはありますか?

$From = "E:\Folder\*"
$To = "\\Server\Folder"
Copy-Item -Path $From -Destination $To -Verbose

答え1

繰り返しますが、あなたが求めていることは で簡単に達成できますRoboCopy.exe。この質問は、ここや他の多くの Q&A サイトで何度も尋ねられてきました。SU でも同じです。

新しいフォルダとファイルのみをコピーするRobocopy

SOと同様に

https://stackoverflow.com/questions/23303532/use-robocopy-to-copy-only-changed-files

RC will only copy newer files. Files of the same age will be skipped.
C:\SourceFolder D:\DestinationFolder ABC.dll /XO

robocopy c:\users\valery\documents j:\robocopy /XO /E /MAXAGE:20131030 /XD
# Result: A full folders tree is created. Only new files copied.

つまり、あなたの質問は実際には上記の質問の重複です。

そうしないと、以下のようなことを知って実行しなければならなくなります (そして、あなたが言うように、初心者であれば、1 回の検索または一連の検索で見つけるのは簡単ではありません)。

Clear-Host
$Source      = 'D:\Temp\Source'
$Destination = 'D:\Temp\Destination'

Get-ChildItem -Path $Source -Recurse | 
ForEach-Object {
    If (Test-Path -Path "$Destination\$($PSItem.Name)")
    {
        Write-Warning -Message "`n$($PSItem.Name) already exists in $Destination. Checking timestamp`n"

        Try
        {
            "Copying file if $($PSItem.Name) is newer"
            Get-ChildItem -Path $Destination -Filter $PSItem.Name | 
            Where-Object LastWriteTime -lt $PSItem.LastWriteTime -ErrorAction Stop
            Copy-Item -Path $PSItem.FullName -Destination $Destination -Verbose -WhatIf

        }
        Catch {$PSItem.Exception.Message}
    }
    Else
    {
        Write-Host "`n$PSItem.Name does not Exist in $Destination`n" -ForegroundColor Cyan
        Copy-Item -Path $PSItem.FullName -Destination $Destination -Verbose -WhatIf
    }
}
# Results
<#
...
WARNING: 
abc.txt already exists in D:\Temp\Destination. Checking timestamp
... 

WARNING: 
LexPointOh.txt already exists in D:\Temp\Destination. Checking timestamp
Copying file if $($PSItem.Name) is newer


-a----         10-Apr-21     00:00              0 LexPointOh.txt
What if: Performing the operation 
"Copy File" on target "Item: D:\Temp\Source\LexPointOh.txt 
Destination: D:\Temp\Destination\LexPointOh.txt".

mytest - Copy.txt.Name does not Exist in D:\Temp\Destination

What if: Performing the operation "Copy File" on target 
"Item: D:\Temp\Source\mytest - Copy.txt 
Destination: D:\Temp\Destination\mytest - Copy.txt".
...
#>

-WhatIf何かを実行するには、を削除するだけです。

したがって、あなたの発言に基づいて言えば、

そのコマンドが何をするのかも完全には理解していません。

そうであれば、私が上で示したものはより難しいものになるでしょう。そのため、私は最初の投稿でヘルプ ファイル (トレーニング サイト、YouTube など) を紹介しました。

上記は、これを行う方法の 1 つにすぎません。PowerShell では、X または Y を実行するためのさまざまな方法が提供されています。たとえば、同じユース ケースを実行する別の方法を次に示します。

Clear-Host

$Source      = ($SourceFiles      = Get-ChildItem -Path 'D:\Temp\Source')[0].DirectoryName
$Destination = ($DestinationFiles = Get-ChildItem -Path 'D:\Temp\Destination')[0].DirectoryName

Compare-Object -ReferenceObject $SourceFiles -DifferenceObject $DestinationFiles -IncludeEqual | 
ForEach-Object {
    If ($PSItem.SideIndicator -match '==|=>')
    {
        If (
            Get-ChildItem -Path $Destination -Filter $($PSItem.InputObject.Name) | 
            Where-Object LastWriteTime -LT  $PSItem.InputObject.LastWriteTime
        )       
        {
            Write-Warning -Message "`n$($PSItem.InputObject) already exists in $Destination. Checking timestamp`n"   
            Copy-Item -Path $PSItem.InputObject.FullName -Destination $Destination -ErrorAction SilentlyContinue -Verbose -WhatIf
        }
    }
    Else
    {
        Write-Host "`n$($PSItem.InputObject ) does not Exist in $Destination`n" -ForegroundColor Cyan
        Copy-Item -Path $PSItem.InputObject.FullName  -Destination $Destination -Verbose -WhatIf
    }
}
# Results
<#
WARNING: 
abc.txt already exists in D:\Temp\Destination. Checking timestamp

What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\abc.txt Destination: D:\Temp\Destination\abc.txt".
WARNING: 
LexPointOh.txt already exists in D:\Temp\Destination. Checking timestamp

What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\LexPointOh.txt Destination: D:\Temp\Destination\LexPointOh.txt".

mytest - Copy.txt does not Exist in D:\Temp\Destination

What if: Performing the operation "Copy File" on target "Item: D:\Temp\Source\mytest - Copy.txt Destination: D:\Temp\Destination\mytest - Copy.txt".

...
#>

ただし、比較ロジックを使用する場合は、ほとんどの場合、単純なコマンドを検討しているわけではありません。

したがって、仕事には適切なツールを使用してください。宿題でない限り、コア作業負荷を増やさないでください。車輪の再発明はしないでください。

答え2

Get-ChildItem コマンドレットを利用できます。スクリプトは基本的に次のフローになります。

  1. ファイルが宛先フォルダに存在するかどうかを確認します
  2. 存在する場合はスキップ
  3. 存在しない場合はコピーする

私は自分のコンピューターで非常に大雑把でシンプルなテストを実行しましたが、これでうまくいくはずです(使用ケースに合わせて変更することを忘れないでください)

$FROM = "T:\Files\Scripts1\BackItUp.ps1"
$TO = "T:\Files2"

if (Get-ChildItem -Path $TO "BackItUp.ps1") {
    Write-Host "file already exists..skipping"
} else {
    Copy-Item $FROM -Destination $TO
}

答え3

Stack Overflow より:

Copy-Item (Join-Path $dir_from "*") $dir_to -Exclude (Get-ChildItem $dir_to)

リンク:Copy-Itemデフォルトで宛先ファイルを上書きするのはなぜですか?

関連情報