我正在尝试将一批文件(文件名以6位开头的文件)从temp文件夹复制到永久位置,但不包括新位置中已经存在的文件。
复制完成后,我想将文件名和复制文件的新路径导出到CSV中。
获取旧文件位置并导出为CSV很容易,我不确定如何获取新文件位置。
我的脚本如下:
# Prompt for file origin
$file_location = Read-Host -Prompt "Where do you want your files to come from?"
# Prompt for file destination
$file_destination = Read-Host -Prompt "Where do you want your files to go? `n(They won't be copied if they're already there)"
# Save contents of file destination - used to check for duplicates
$dest_contents = Get-ChildItem $file_destination
<# For all of the files of interest (those whose names begin with 6 digits) in $file_location,
determine whether that filename already exists in the target directory ($file_destination)
If it doesn't, copy the file to the destination
Then save the filename and the new** filepath to a CSV #>
Get-ChildItem -Path $file_location |
Where-Object { $_.Name -match '^\d{6}' -And !($dest_contents -Match $_.Name ) } |
Copy-Item -Destination $file_destination -PassThru |
Select-Object -Property Name, FullName | # **Note: This saves the old filepath, not the new one
Export-CSV -Path "$file_location\files_copied.csv" -NoClobber
答案 0 :(得分:1)
您可以对代码进行一些更改
# Prompt for file origin
$file_location = Read-Host -Prompt "Where do you want your files to come from?"
# Prompt for file destination
$file_destination = Read-Host -Prompt "Where do you want your files to go? `n(They won't be copied if they're already there)"
# Save contents of file destination - used to check for duplicates
$dest_contents = Get-ChildItem $file_destination | Select-Object -ExpandProperty Name
<# For all of the files of interest (those whose names begin with 6 digits) in $file_location,
determine whether that filename already exists in the target directory ($file_destination)
If it doesn't, copy the file to the destination
Then save the filename and the new** filepath to a CSV #>
Get-ChildItem -Path $file_location |
Where-Object { $_.Name -match '^\d{6}' -and ($dest_contents -notcontains $_.Name ) } |
ForEach-Object {
Copy-Item -Path $_.FullName -Destination $file_destination
# emit a PSObject storing the Name and (destination) FullName of the file that has been copied
# This will be used to generate the output in the 'files_copied.csv'
New-Object -TypeName PSObject -Property ([ordered]@{ Name = $_.Name; FullName = (Join-Path $file_destination $_.Name)})
} |
Export-CSV -Path "$file_location\files_copied.csv" -NoTypeInformation -Force
请注意,我只收集目标路径中已经存在的文件的名称,而不是fileInfo对象。这使它变得“精简”得多,因为收集的唯一原因是要收集要比较的文件名。
现在,您已经为“ files_copied.csv”使用了固定的名称,我个人认为,通过在其上添加当前日期(例如)来使其更通用,是一个好主意
Export-CSV -Path ("{0}\files_copied_{1}.csv" -f $file_location, (Get-Date).ToString("yyyy-MM-dd")) -NoTypeInformation -Force
P.s。我在这里使用[ordered]
,因此输出将始终具有相同顺序的属性。但是,这需要PowerShell v3或更高版本。
另外,如果您需要确保代码仅复制文件而不是目录,则建议查看-File
命令上的-Attributes
或Get-ChildItem
开关。如果您的PowerShell版本是2.0,则可以使用Where-Object { !$_.PSIsContainer }
构造仅过滤掉文件。
答案 1 :(得分:0)
我将使用另一种方法测试迭代源文件时是否存在目标。
要附加到当前的csv(日志)文件中,您需要删除新文件的标题。
## Q:\Test\2018\08\08\SO_51738853.ps1
# Prompt for file origin
$SrcDir = Read-Host -Prompt "Where do you want your files to come from?"
# Prompt for file destination
$DstDir = Read-Host -Prompt "Where do you want your files to go? `n(They won't be copied if they're already there)"
$SrcFiles = Join-Path (Get-Item $SrcDir).Fullname [0-9][0-9][0-9][0-9][0-9][0-9]*
$CopiedFiles = ForEach ($SrcFile in (Get-ChildItem -Path $SrcFiles)){
$DstFile = Join-Path $DstDir $SrcFile.Name
If (!(Test-Path $DstFile)){
$SrcFile | Copy-Item -Destination $DstFile -PassThru |
Select-Object -Property Name, FullName
}
}
# Check if log file exists, if yes append, otherwise export.
$LogFile = Join-Path $SrcDir "files_copied.csv"
If ($CopiedFiles){
If (!(Test-Path $LogFile)){
Export-CSV -Path $LogFile -InputObject $CopiedFiles -NoTypeInformation
} else {
# We need to remove the Header appending to the present csv
$CopiedFiles | ConvertTo-Csv -NoType | Select-Object -Skip 1 | Add-Content -Path $LogFile
}
}