Powershell - 查找包含文本的文件并将它们复制到新文件夹,重命名重复项
Powershell - find files containing text and copy them to new folder, rename duplicates
我正在用 Powershell 编写应用程序。该应用程序用于通过文件名中的字符串在源位置查找文件。必须将找到的文件复制到新位置。
我预计可能会有重复,并且必须在文件名末尾添加一个数字。
最后搜索到的字符串必须替换为新字符串(但我已经知道了)
我找到了一个脚本,它完全符合我的要求,但适用于位置上的所有文件,但不适用于搜索精确的字符串。我试过写一个,但有重复的问题...帮助已确定!
#### Function to check if duplicates exist and copy files ####
function fcopy ($SourceDir,$DestinationDir)
{
Get-ChildItem $SourceDir -Recurse | Where-Object { $_.PSIsContainer -eq $false } | ForEach-Object ($_) {
$SourceFile = $_.FullName
$DestinationFile = $DestinationDir + $_
if (Test-Path $DestinationFile) {
$i = 0
while (Test-Path $DestinationFile) {
$i += 1
$DestinationFile = $DestinationDir + $_.basename + $i + $_.extension
}
} else {
Copy-Item -Path $SourceFile -Destination $DestinationFile -Verbose -Force
}
Copy-Item -Path $SourceFile -Destination $DestinationFile -Verbose -Force
}
}
##### Call fcopy function ######
fcopy -SourceDir $source -DestinationDir $destination
您可以使用下面的功能。如果目标文件夹中已存在具有重复名称的文件,它将复制与 -Filter
模式匹配的文件并在其名称后附加序列号:
function Copy-Unique {
# Copies files to a destination. If a file with the same name already exists in the destination,
# the function will create a unique filename by appending '(x)' after the name, but before the extension.
# The 'x' is a numeric sequence value.
[CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'ByPath')] # add support for -WhatIf switch
Param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = 'ByPath')]
[Alias("Source")]
[ValidateScript({Test-Path -Path $_ -PathType Container})]
[string]$Path,
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = 'ByLiteralPath')]
[ValidateScript({Test-Path -LiteralPath $_ -PathType Container})]
[string]$LiteralPath,
[Parameter(Mandatory = $true, Position = 1)]
[string]$Destination,
[Parameter(Mandatory = $false)]
[string]$Filter = '*', # by default, filter allows any file pattern
[switch]$Recurse
)
# create the destination path if it does not exist
if (!(Test-Path -Path $Destination -PathType Container)) {
Write-Verbose "Creating folder '$Destination'"
$null = New-Item -Path $Destination -ItemType 'Directory' -Force
}
# get a list of file FullNames in this source folder
if ($PSCmdlet.ParameterSetName -eq 'ByLiteralPath') {
$sourceFiles = @(Get-ChildItem -LiteralPath $LiteralPath -Filter $Filter -File -Recurse:$Recurse)
}
else {
$sourceFiles = @(Get-ChildItem -Path $Path -Filter $Filter -File -Recurse:$Recurse)
}
foreach ($file in $sourceFiles) {
# get an array of all filenames (names only) of the files with a similar name already present in the destination folder
$destFiles = @((Get-ChildItem $Destination -File -Filter "$($file.BaseName)*$($file.Extension)").Name)
# for PowerShell version < 3.0 use this
# $destFiles = @(Get-ChildItem $Destination -Filter "$baseName*$extension" | Where-Object { !($_.PSIsContainer) } | Select-Object -ExpandProperty Name)
# construct the new filename
$newName = $file.Name
$count = 1
while ($destFiles -contains $newName) {
$newName = "{0}({1}){2}" -f $file.BaseName, $count++, $file.Extension
}
# use Join-Path to create a FullName for the file
$newFile = Join-Path -Path $Destination -ChildPath $newName
Write-Verbose "Copying '$($file.FullName)' as '$newFile'"
$file | Copy-Item -Destination $newFile -Force
}
}
# you can change the folder paths, file pattern to filter etc. here
Copy-Unique -Path 'D:\Test' -Destination 'D:\Destination' -Filter '*.ps1' -Recurse
我正在用 Powershell 编写应用程序。该应用程序用于通过文件名中的字符串在源位置查找文件。必须将找到的文件复制到新位置。
我预计可能会有重复,并且必须在文件名末尾添加一个数字。
最后搜索到的字符串必须替换为新字符串(但我已经知道了)
我找到了一个脚本,它完全符合我的要求,但适用于位置上的所有文件,但不适用于搜索精确的字符串。我试过写一个,但有重复的问题...帮助已确定!
#### Function to check if duplicates exist and copy files ####
function fcopy ($SourceDir,$DestinationDir)
{
Get-ChildItem $SourceDir -Recurse | Where-Object { $_.PSIsContainer -eq $false } | ForEach-Object ($_) {
$SourceFile = $_.FullName
$DestinationFile = $DestinationDir + $_
if (Test-Path $DestinationFile) {
$i = 0
while (Test-Path $DestinationFile) {
$i += 1
$DestinationFile = $DestinationDir + $_.basename + $i + $_.extension
}
} else {
Copy-Item -Path $SourceFile -Destination $DestinationFile -Verbose -Force
}
Copy-Item -Path $SourceFile -Destination $DestinationFile -Verbose -Force
}
}
##### Call fcopy function ######
fcopy -SourceDir $source -DestinationDir $destination
您可以使用下面的功能。如果目标文件夹中已存在具有重复名称的文件,它将复制与 -Filter
模式匹配的文件并在其名称后附加序列号:
function Copy-Unique {
# Copies files to a destination. If a file with the same name already exists in the destination,
# the function will create a unique filename by appending '(x)' after the name, but before the extension.
# The 'x' is a numeric sequence value.
[CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'ByPath')] # add support for -WhatIf switch
Param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = 'ByPath')]
[Alias("Source")]
[ValidateScript({Test-Path -Path $_ -PathType Container})]
[string]$Path,
[Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0, ParameterSetName = 'ByLiteralPath')]
[ValidateScript({Test-Path -LiteralPath $_ -PathType Container})]
[string]$LiteralPath,
[Parameter(Mandatory = $true, Position = 1)]
[string]$Destination,
[Parameter(Mandatory = $false)]
[string]$Filter = '*', # by default, filter allows any file pattern
[switch]$Recurse
)
# create the destination path if it does not exist
if (!(Test-Path -Path $Destination -PathType Container)) {
Write-Verbose "Creating folder '$Destination'"
$null = New-Item -Path $Destination -ItemType 'Directory' -Force
}
# get a list of file FullNames in this source folder
if ($PSCmdlet.ParameterSetName -eq 'ByLiteralPath') {
$sourceFiles = @(Get-ChildItem -LiteralPath $LiteralPath -Filter $Filter -File -Recurse:$Recurse)
}
else {
$sourceFiles = @(Get-ChildItem -Path $Path -Filter $Filter -File -Recurse:$Recurse)
}
foreach ($file in $sourceFiles) {
# get an array of all filenames (names only) of the files with a similar name already present in the destination folder
$destFiles = @((Get-ChildItem $Destination -File -Filter "$($file.BaseName)*$($file.Extension)").Name)
# for PowerShell version < 3.0 use this
# $destFiles = @(Get-ChildItem $Destination -Filter "$baseName*$extension" | Where-Object { !($_.PSIsContainer) } | Select-Object -ExpandProperty Name)
# construct the new filename
$newName = $file.Name
$count = 1
while ($destFiles -contains $newName) {
$newName = "{0}({1}){2}" -f $file.BaseName, $count++, $file.Extension
}
# use Join-Path to create a FullName for the file
$newFile = Join-Path -Path $Destination -ChildPath $newName
Write-Verbose "Copying '$($file.FullName)' as '$newFile'"
$file | Copy-Item -Destination $newFile -Force
}
}
# you can change the folder paths, file pattern to filter etc. here
Copy-Unique -Path 'D:\Test' -Destination 'D:\Destination' -Filter '*.ps1' -Recurse