将文件复制到目录,同时保留列表中的目录结构

Copying files to directory whilst retaining directory structure from list

大家下午好,

我猜这很简单,但对我来说真的很烦人;我有一个包含文件列表的文本文件,在同一文件夹中还有很多其他文件,但我只需要特定的文件。

$Filelocs = get-content "C:\Users\me\Desktop\tomove\Code\locations.txt"

Foreach ($Loc in $Filelocs){xcopy.exe $loc C:\Redacted\output /s }

我想这会遍历列表,就像

"C:\redacted\Policies\IT\Retracted Documents\Policy_Control0.docx"

然后移动并在新位置创建文件夹结构,然后复制文件,它没有。

如有任何帮助,我们将不胜感激。

谢谢 RGE

当您显式传递源文件路径而不是源目录时,

xcopy 无法知道文件夹结构。在像 C:\foo\bar\baz.txt 这样的路径中,基本目录可以是 C:\C:\foo\C:\foo\bar\.

中的任何一个

使用路径列表时,您必须自己构建目标目录结构。将文本文件的路径解析为相对路径,加入目标目录,创建文件的父目录,最后使用 PowerShell 自带的 Copy-Item 命令复制文件。

$Filelocs = Get-Content 'locations.txt'

# Base directory common to all paths specified in "locations.txt"
$CommonInputDir = 'C:\redacted\Policies'

# Where files shall be copied to
$Destination = 'C:\Redacted\output'

# Temporarily change current directory -> base directory for Resolve-Path -Relative
Push-Location $CommonInputDir

Foreach ($Loc in $Filelocs) {

    # Resolve input path relative to $CommonInputDir (current directory)  
    $RelativePath = Resolve-Path $Loc -Relative

    # Resolve full target file path and directory
    $TargetPath   = Join-Path $Destination $RelativePath
    $TargetDir    = Split-Path $TargetPath -Parent

    # Create target dir if not already exists (-Force) because Copy-Item fails 
    # if directory does not exist.
    $null = New-Item $TargetDir -ItemType Directory -Force

    # Well, copy the file
    Copy-Item -Path $loc -Destination $TargetPath
}

# Restore current directory that has been changed by Push-Location
Pop-Location

可能的改进,留作练习:

  • 自动确定“locations.txt”中指定文件的公共基目录。不简单但也不太难。
  • 制作代码exception-safe。将 Push-LocationPop-Location 之间的所有内容包装在 try{} 块中,并将 Pop-Location 移动到 finally{} 块中,这样即使 [=36] 也会恢复当前目录=] 发生错误。参见 about_Try Catch_Finally