首页 > 解决方案 > 如何通过使用 Powershell 查找每个文件夹名称中包含的匹配字符串来将文件夹复制到另一个文件夹

问题描述

我是新手,所以希望我做对了。在过去的几天里,我做了很多研究,我一直在努力处理这段代码,但我就是无法让它做我想做的事。

我有一个包含多个目录的源目录。我有一个包含多个目录的目标目录。目录名称中都有一个四位数字,但不在名称的同一位置。我想在每个源目录的名称中找到该编号,并使用该编号在目标目录中查找名称中具有相同编号的目录。一旦我找到匹配的目标目录,将源目录与文件夹名称 33-fit-1234 一起移动到具有匹配编号的目标目录中,即。33-F-1234。我目前正在通过复制然后删除源来进行移动。

源文件夹名称可以是 33-ait-1743A 或 33-xx-4533 UNKNOWN 等。
目标文件夹名称的格式都为:33-x-####,有的带有单个字母后缀,例如 A 、乙等。

这是代码:

$sourceDirectory = "D:\Test Source"
$destinationDirectory = "D:\Test Dest"

$sourceFolders = Get-ChildItem -Path $sourceDirectory -Directory | Select-Object -ExpandProperty Name
$destinationFolders = Get-ChildItem -Path $destinationDirectory -Directory | Select-Object -ExpandProperty Name
$matchesInBoth = $sourceFolders -match "\d{4}" | ?{$_ -eq $_}
$matchesInBoth | ForEach-Object{
    $sourcePath = (Join-Path $sourceDirectory $_)
    Copy-Item -Path $sourcePath -Destination 
$destinationDirectory\$matchesInBoth\$_ -Recurse -whatif
    Remove-Item $sourcePath -Force -Recurse -WhatIf 
}

它很接近,我得到的输出是:

What if: Performing the operation "Copy Directory" on target "Item: D:\Test 
Source\33-FV-1414 Destination: D:\Test Dest\33-FIT-1414 33-FIT-1576 33-FIT- 
1654A 33-fred-1234 unknown 33-FSL-1649 33-FV-1414 33-FV-1654 33-FV-1882 
33-H-1657 33-H-1814 33-H-1924\33-FV-1414".
What if: Performing the operation "Remove Directory" on target "D:\Test 
Source\33-FV-1414".

问题是:我最终将源文件夹复制到一个以源目录中所有文件夹名称命名的新文件夹中。

我也试过这段代码没有结果:

$sourceDirectory = "D:\Test Source"
$destinationDirectory = "D:\Test Dest"

$sourceFolders = Get-ChildItem -Path $sourceDirectory -Directory | Select-    Object -ExpandProperty BaseName | Select-String "\d{4}"
$destinationFolders = Get-ChildItem -Path $destinationDirectory -Directory | Select-Object -ExpandProperty BaseName

$matchesInBoth = $destinationFolders | ?{$_ -contains $sourceFolders}
$matchesInBoth | ForEach-Object{
$sourcePath = (Join-Path $sourceDirectory $_)
Copy-Item -Path $sourcePath -Destination $destinationDirectory\$matchesInBoth\$_ -Recurse -whatif
Remove-Item $sourcePath -Force -Recurse -WhatIf 
}

源文件夹名称为:

"D:\Test Source\33-FIT-1414"
"D:\Test Source\33-FIT-1576"
"D:\Test Source\33-FIT-1654A"
"D:\Test Source\33-fred-1234 unknown"
"D:\Test Source\33-FSL-1649"
"D:\Test Source\33-FV-1414"
"D:\Test Source\33-FV-1654"
"D:\Test Source\33-FV-1882"
"D:\Test Source\33-H-1657"
"D:\Test Source\33-H-1814"
"D:\Test Source\33-H-1924"
"D:\Test Source\asjhdsdlljhsdflj"

目标文件夹名称为:

"D:\Test Dest\33"
"D:\Test Dest\33-F-1108"
"D:\Test Dest\33-F-1111"
"D:\Test Dest\33-F-1120"
"D:\Test Dest\33-F-1125"
"D:\Test Dest\33-F-1130"
"D:\Test Dest\33-F-1135"
"D:\Test Dest\33-F-1209"
"D:\Test Dest\33-F-1223"
"D:\Test Dest\33-F-1252"
"D:\Test Dest\33-F-1254"
"D:\Test Dest\33-F-1307"
"D:\Test Dest\33-F-1309"
"D:\Test Dest\33-F-1317"
"D:\Test Dest\33-F-1351"
"D:\Test Dest\33-F-1414"
"D:\Test Dest\33-F-1426"
"D:\Test Dest\33-F-1428"
"D:\Test Dest\33-F-1432"
"D:\Test Dest\33-F-1433"
"D:\Test Dest\33-F-1434"
"D:\Test Dest\33-F-1435"
"D:\Test Dest\33-F-1451"
"D:\Test Dest\33-F-1476"
"D:\Test Dest\33-F-1526"
"D:\Test Dest\33-F-1528"
"D:\Test Dest\33-F-1532"
"D:\Test Dest\33-F-1533"
"D:\Test Dest\33-F-1554"
"D:\Test Dest\33-F-1565"
"D:\Test Dest\33-F-1576"
"D:\Test Dest\33-F-1623"
"D:\Test Dest\33-F-1626"
"D:\Test Dest\33-F-1649"
"D:\Test Dest\33-F-1654"
"D:\Test Dest\33-F-1659"
"D:\Test Dest\33-F-1671"
"D:\Test Dest\33-F-1709"
"D:\Test Dest\33-F-1712"
"D:\Test Dest\33-F-1799"
"D:\Test Dest\33-F-1800"
"D:\Test Dest\33-F-1801"
"D:\Test Dest\33-F-1882"
"D:\Test Dest\33-F-1883"
"D:\Test Dest\33-F-2000"
"D:\Test Dest\33-F-2001"
"D:\Test Dest\33-F-2002"
"D:\Test Dest\33-ggg-1234"
"D:\Test Dest\1234"
"D:\Test Dest\daddybear"

想法?

标签: powershellpowershell-5.0

解决方案


你的问题很模棱两可

  • 在你想要复制的标题中,
  • 文字说移动
  • 代码复制和删除源而不是使用Move-Item

## Q:\Test\2018\10\18\SO_52866947.ps1
$SrcDir = "A:\Test\Source"
$DstDir = "A:\Test\Dest"

# Build hash table from Destination with 4digit key and Directory FullName as value
$DstHash = @{}
Get-ChildItem $DstDir -Directory | Where-Object Name -match '\d{4}'| ForEach-Object {
    $DstHash.$($Matches.Values)=$_.FullName
}

# Iterate source and check if destination key/value pair exists
Get-ChildItem $SrcDir -Directory | Where-Object Name -match '\d{4}'| ForEach-Object {
    if ($DstHash.ContainsKey($($Matches.Values))){
        "Move {0} to {1}" -f $_.FullName, $DstHash.$($Matches.Values)
        Move-Item $_.FullName -Destination $DstHash.$($Matches.Values) -Force
    } else {
        "no corresponding Destination found for: {0}" -f $_.FullName
    }
}

示例输出:(
在我的 ramdrive A 上有文件夹:)

> Q:\Test\2018\10\18\SO_52866947.ps1
Move A:\Test\Source\33-FIT-1414 to A:\Test\Dest\33-F-1414
Move A:\Test\Source\33-FIT-1576 to A:\Test\Dest\33-F-1576
Move A:\Test\Source\33-FIT-1654A to A:\Test\Dest\33-F-1654
Move A:\Test\Source\33-fred-1234 unknown to A:\Test\Dest\33-ggg-1234
Move A:\Test\Source\33-FSL-1649 to A:\Test\Dest\33-F-1649
Move A:\Test\Source\33-FV-1414 to A:\Test\Dest\33-F-1414
Move A:\Test\Source\33-FV-1654 to A:\Test\Dest\33-F-1654
Move A:\Test\Source\33-FV-1882 to A:\Test\Dest\33-F-1882
no corresponding Destination found for: A:\Test\Source\33-H-1657
no corresponding Destination found for: A:\Test\Source\33-H-1814
no corresponding Destination found for: A:\Test\Source\33-H-1924

推荐阅读