我想為一組檔案夾創建一個 0 檔案大小的鏡像,但是雖然 robocopy 非常好,但它并沒有保存我想要的所有資訊:
robocopy D:\documents E:\backups\documents_$(Get-Date -format "yyyyMMdd_HHmm")\ /mir /create
該/create開關使重復檔案夾中的每個檔案的大小為零,這很好,但我希望重復檔案夾中的每個檔案都[size]附加到名稱的末尾,大小為 KB 或 MB 或 GB,并且在每個檔案上創建/上次修改時間以完全匹配原始檔案。這樣,我將擁有一個可以存檔的檔案夾的零大小副本,但其中包含該目錄中檔案的所有相關資訊,顯示每個檔案的大小以及確切的創建/上次修改時間。
是否有好的/簡單的方法來遍歷 PowerShell 中的樹,并為每個專案創建一個包含所有相關資訊的零大小檔案?
uj5u.com熱心網友回復:
這將是使用我在評論中提到的方法來實作復制命令的一種方法。我認為為了學習而自己解決它會更好——這個例子可以在引數處理方面得到改進。但它應該給你一些可以從中汲取靈感的東西。
function Copy-FolderZeroSizeFiles {
[CmdletBinding()]
param( [Parameter(Mandatory)] [string] $FolderPath,
[Parameter(Mandatory)] [string] $DestinationPath )
# Make sure dest exists.
New-Item $DestinationPath -Type Directory -Force
# Ensure dest is not a relative path since we change the working directory.
$destFullPath = Resolve-Path $DestinationPath
try {
# Here we change the working directory of the process.
Push-Location $FolderPath
foreach ($item in Get-ChildItem '.' -Recurse) {
$relPath = Resolve-Path $item -Relative
$type = ($item.Attributes -match 'Directory') ? 'Directory' : 'File'
$new = New-Item "$destFullPath\$relPath" -ItemType $type
$new.Attributes = $item.Attributes
$new.LastWriteTime = $item.LastWriteTime
}
} finally {
# Silently set process back to its original working directory.
Pop-Location | Out-Null
}
}
注意:上面的實作很簡單,將任何不是目錄的東西都表示為檔案。這意味著符號鏈接等。將是沒有資訊的檔案,它們將鏈接到什么。
這是一個將位元組數轉換為 NN B/K/M/G 格式的函式。要獲得更多小數位,只需0在格式字串的末尾添加 's。
function ConvertTo-FriendlySize($NumBytes) {
switch ($NumBytes) {
{$_ -lt 1024} { "{0,7:0.0}B" -f ($NumBytes) ; break }
{$_ -lt 1048576} { "{0,7:0.0}K" -f ($NumBytes / 1024) ; break }
{$_ -lt 1073741824} { "{0,7:0.0}M" -f ($NumBytes / 1048576) ; break }
default { "{0,7:0.0}G" -f ($NumBytes / 1073741824); break }
}
}
通常,人們會錯誤地進行這些轉換。例如,使用 1024 * 1000 來獲取兆位元組(這是將 1K 的 base10 值與 1K 的 base2 值混合)并遵循相同的邏輯來獲取 GB 和 TB 是一個常見錯誤。
uj5u.com熱心網友回復:
這是我在問題中提出的附加部分,根據需要更改$src/ $dst(D:\VMs我保留了很多虛擬機)。我已經包括設定所有 CreationTime、LastWriteTime、LastAccessTime 以便具有零大小檔案的備份位置是源的完美表示。因為我想將它用于存檔目的,所以我終于壓縮了東西,并在 zipfile 名稱中包含了一個日期時間戳。
# Copy-FolderZeroSizeFiles
$src = "D:\VMs"
$dst = "D:\VMs-Backup"
function ConvertTo-FriendlySize($NumBytes) {
switch ($NumBytes) {
{$_ -lt 1024} { "{0:0.0}B" -f ($NumBytes) ; break } # Change {0: to {0,7: to align to 7 characters
{$_ -lt 1048576} { "{0:0.0}K" -f ($NumBytes / 1024) ; break }
{$_ -lt 1073741824} { "{0:0.0}M" -f ($NumBytes / 1048576) ; break }
default { "{0:0.0}G" -f ($NumBytes / 1073741824); break }
}
}
function Copy-FolderZeroSizeFiles($FolderPath, $DestinationPath) {
Push-Location $FolderPath
if (!(Test-Path $DestinationPath)) { New-Item $DestinationPath -Type Directory }
foreach ($item in Get-ChildItem $FolderPath -Recurse -Force) {
$relPath = Resolve-Path $item.FullName -Relative
if ($item.Attributes -match 'Directory') {
$new = New-Item "$DestinationPath\$relPath" -ItemType Directory -Force -EA Silent
}
else {
$fileBaseName = [System.IO.Path]::GetFileNameWithoutExtension($item.Name)
$fileExt = [System.IO.Path]::GetExtension($item.Name)
$fileSize = ConvertTo-FriendlySize($item.Length)
$new = New-Item "$DestinationPath\$(Split-Path $relPath)\$fileBaseName ($fileSize)$fileExt" -ItemType File
}
"$($new.Name) : creation $($item.CreationTime), lastwrite $($item.CreationTime), lastaccess $($item.LastAccessTime)"
$new.CreationTime = $item.CreationTime
$new.LastWriteTime = $item.LastWriteTime
$new.LastAccessTime = $item.LastAccessTime
$new.Attributes = $item.Attributes # Must this after setting creation/write/access times or get error on Read-Only files
}
Pop-Location
}
Copy-FolderZeroSizeFiles $src $dst
$dateTime = Get-Date -Format "yyyyMMdd_HHmm"
$zipName = "$([System.IO.Path]::GetPathRoot($dst))\$([System.IO.Path]::GetFileName($dst))_$dateTime.zip"
Add-Type -AssemblyName System.IO.Compression.FileSystem
[IO.Compression.ZipFile]::CreateFromDirectory($dst, $zipName)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/462509.html
上一篇:如何插入額外的所需列和行?
