1

我有一个非常大的目录D:\Stuff,我想在 上创建它的副本D:\CopyStuff,但我只想获取具有特定扩展名的文件并保留文件夹结构。

获取我想要的文件似乎很简单:

$from = "D:\stuff"
$to = "D:\CopyStuff"   
$files = Get-ChildItem -Recurse -Path $from -Include *.config, *.txt, *.ini 

但是,复制文件并保持结构更具挑战性。我可以使用 for 循环,但这似乎与 Powershell 的本质背道而驰。这里https://stackoverflow.com/a/25780745/782880,它建议这样做:

Get-ChildItem -Path $sourceDir | Copy-Item -Destination $targetDir -Recurse -Container

但这将文件复制到D:\CopyStuff没有文件夹,更不用说我的原始结构了。我究竟做错了什么?我正在使用 Powershell 5。

4

3 回答 3

2

尝试这个 :

$Source="C:\temp\test1"
$Dest="C:\temp\test2"
$EnableExt=".config", ".txt" , ".ini"

Get-ChildItem $Source -Recurse | % {

    $NewPath=$_.FullName.Replace($Source, $Dest)

    if ($_.psiscontainer)
    {
        New-Item -Path $NewPath -ItemType Directory -Force
    }
    elseif ($_.Extension -in $EnableExt)
    {
        Copy-Item $_.FullName $NewPath -Force
    }
}
于 2019-01-05T09:47:35.237 回答
1

首先,Copy-Item可以自己做:

$fromFolder = "C:\Temp\Source"
$toFolder = "C:\Temp\Dest"
Copy-Item -Path $fromFolder -Destination $toFolder -Recurse -Filter *.txt

但是,您可能不喜欢这样的结果:它会在“Dest”文件夹中创建文件夹“Source”,然后复制结构。我认为,您需要将“源”文件夹中的相同文件/文件夹复制到“目标”文件夹。嗯,它有点复杂,但这里是:

$fromFolder = "C:\Temp\Source"
$toFolder = "C:\Temp\Dest"

Get-ChildItem -Path $fromFolder -Directory -Recurse | Select-Object FullName, @{N="NewPath";E={$_.FullName.Replace($fromFolder, $toFolder)}} | ForEach-Object { New-Item -Path $_.NewPath -ItemType "Directory" }
Get-ChildItem -Path $fromFolder -Include "*.txt" -Recurse | Select-Object FullName, @{N="NewPath";E={$_.FullName.Replace($fromFolder, $toFolder)}} | ForEach-Object { Copy-Item -Path $_.FullName -Destination $_.NewPath }

它首先复制文件夹结构,然后是文件。

注意!我强烈建议只使用绝对路径。否则,该Replace方法可能会产生意想不到的结果。

于 2019-01-05T07:12:35.570 回答
0

注意:下面的解决方案仅为那些包含与-Include过滤器匹配的文件的源文件夹创建类似的目标文件夹,而不是为所有源文件夹创建类似的目标文件夹。


您可以通过结合延迟绑定脚本块来摆脱单管道解决方案:Get-ChildItem -Name

$from = 'D:\stuff'
$to = 'D:\CopyStuff'

Get-ChildItem -Name -Recurse -LiteralPath $from -Include *.config, *.txt, *.ini |
  Copy-Item `
    -LiteralPath { Join-Path $from $_ } `
    -Destination { New-Item -Type Directory -Force (Split-Path (Join-Path $to $_)) }
  • -Name以字符串形式发出对于输入目录的路径。

  • 延迟绑定脚本块从每个相对输入路径{ Join-Path $from $_ }构建完整的输入文件名。

  • 延迟绑定脚本块从目标根路径和相对输入路径{ New-Item -Type Directory -Force (Split-Path (Join-Path $to $_)) }构建目标目录-Force的完整路径,并根据需要创建该目录,如果存在则使用预先存在的目录 ( )。

于 2019-01-05T09:46:19.523 回答