【问题标题】:Why is this PowerShell script constructing unexpected file paths?为什么这个 PowerShell 脚本会构建意外的文件路径?
【发布时间】:2013-09-10 23:45:39
【问题描述】:

使用从thisthisthis 收集到的提示,我终于能够启动一系列文件备份脚本。但是,有一件小事我一直无法解决。没有运行时错误,但是当我运行这个脚本时,

$originalPath = "\\Server\Path\_testData\"
$backupPath   = "\\Server\Path\_backup\"
#       
function supportBackup 
{
  "$($originalPath) copying DOC XLS PPT JPG GIF PDF WAV AVI to $($backupPath)"
  Get-ChildItem $originalPath\* -Include *.doc*, *.xls*, *.ppt*, *.jpg, *.gif, *.pdf, *.wav, *.avi | `
  foreach { 
    $targetFile = $backupPath + $_.FullName.SubString($originalPath.Length); 
    New-Item -ItemType File -Path $targetFile -Force;  
    Copy-Item $_.FullName -destination $targetFile 
  } 
  "Support File Backup Completed"
} 
supportBackup

原始文件路径被转储到目标目录而不是只是文件。

我想要什么:

\\Server\Path\_backup\files-from-testData-directory

我得到了什么:

\\Server\Path\_backup\_testData\files-from-testData-directory

我知道这个问题与this question 密切相关(如果不相同),但是在研究它并尝试从那里应用一些智慧之后,使用$_.Name 变量的各种迭代,我意识到我没有没有我想象的那么好理解。我需要有人向我解释如何使用给定的变量构建目标路径和文件名,以及我需要使用哪些替代变量(或代码)来实现我想要的结果。有些东西对我来说没有点击,我需要帮助来理解它。

【问题讨论】:

  • 仅供参考,如果以管道符号结束一行,则不需要反引号。 PowerShell 自动将以下行解释为继续管道。但是,我个人发现用管道符号 begin 行更清晰,因此更清楚地看到多行管道中的内容是什么。在这种情况下,您 确实 需要在前一行的末尾添加一个反引号,以转义换行符。所以,我会用反引号结束第 7 行,并将第 8 行更改为:|foreach {。这不是一种常见的风格,但我认为它使复杂的管道更容易遵循。

标签: variables powershell powershell-2.0 file-copying


【解决方案1】:

你太努力了。这应该足够了:

$originalPath = '\\Server\Path\_testData'
$backupPath   = '\\Server\Path\_backup'
$extensions   = *.doc*,*.xls*,*.ppt*,*.jpg,*.gif,*.pdf,*.wav,*.avi

function supportBackup {
  "$($originalPath) copying DOC XLS PPT JPG GIF PDF WAV AVI to $($backupPath)"
  Get-ChildItem "$originalPath\*" -Include $extensions |
    Copy-Item -Destination "$backupPath\" -Force 
  "Support File Backup Completed"
} 

supportBackup

您可以将Get-ChildItem 的结果直接通过管道传输到Copy-File。但是,目标路径必须以反斜杠结尾,否则该指令会尝试将文件夹 $backupPath 替换为同名文件,从而导致错误。

【讨论】:

  • 就副本而言,这完成了我所需要的...但是我的文件名在复制时不会打印到控制台。我现在可以没有它。 :)
  • 如果您需要将文件名回显到成功流或控制台,您可以将Copy-Item -Destination "$backupPath\" -Force 替换为% { Copy-Item $_.FullName -Destination "$backupPath\" -Force; Write-Output $_.FullName }。使用Write-Host 而不是Write-Output 回显到控制台(不能重定向到输出文件)。请注意,在控制台窗口中显示文件名会大大降低性能。
  • 谢谢,是的...我注意到性能下降,但对于我的测试,我喜欢增加的安全性。我上面的原始代码回显文件名......但没有写主机;你知道哪个部分回显到控制台,那里是否有一些隐含的写入控制台?
  • Write-Output 写入成功输出流 (vulgo STDOUT),可以重定向到文件。 Write-Host 写入控制台,因此无法将此输出重定向到文件。根据您的要求使用其中一种。
猜你喜欢
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 2011-09-02
  • 1970-01-01
  • 2021-08-10
  • 1970-01-01
  • 1970-01-01
  • 2020-10-13
相关资源
最近更新 更多