PowerShell:在文件夹顶层搜索文件路径;如果未找到则警告用户并继续递归搜索

PowerShell:在文件夹顶层搜索文件路径;如果未找到则警告用户并继续递归搜索

我正在编写一个自动评分脚本,当学生没有遵守目录要求时,它会向用户发出警告:具体来说,单身的文件,main.cpp位于适当命名的文件夹中。如果在顶层找不到该文件,则警告用户,但继续在任何子目录中递归查找该文件。如果找不到文件,则发送错误,但继续处理父目录中的其余目录。

这是我迄今为止的尝试,但效果并不好——即使用户已经 main.cpp当我只想要 3 个可能的输出时,我根本不需要文件:

  1. 没有任何警告,继续建造;
  2. 递归找到文件,但发送了警告;
  3. 未找到文件且出错,但继续处理其他文件夹。

我该如何修复它?

function Copy-Files {
    param (
        [Parameter(Mandatory)][string]$CurrentDir,
        [Parameter(Mandatory)][string]$StudentNum
    )

    # Try to copy assignment files to the marking folder. Check error conditions and warn marker appropriately.
    try {
        $DoneFiles | ForEach-Object {
            Copy-Item -Force -Path "$CurrentDir\$_" -Destination .\marking -ErrorAction Stop
        }
    }
    catch {
        try {
            $DoneFiles | ForEach-Object {
                Get-ChildItem -Path $CurrentDir -File -Recurse -Filter "$_" | Copy-Item -Force -Destination .\marking -ErrorAction Stop
            }
            Write-Warning "$StudentNumber did not follow the specified folder convention, but all files were submitted."
        }
        catch {
            Write-Error -Message "$StudentNumber did not submit any of: $DoneFiles." -Category InvalidData
            Read-Host -Prompt "Press Enter to continue"
        }
    }
}

Get-ChildItem -Directory -Filter "*_lab${Env:AssignNumber}" | ForEach-Object {
    $CurrentFolder = $_
    $StudentNumber = $CurrentFolder.Name.Replace("_lab${Env:AssignNumber}", "")

    Copy-Files -CurrentDir $CurrentFolder -StudentNum $StudentNumber

    if ($AllFound -and $IsCMake) {
        Invoke-CMake -DoneFileNames $DoneFiles -IsFirstCompile $FirstCompile -StudentNum $StudentNumber
    }
    # Run VS Code with diff
    Compare-Code -DoneFileNames $DoneFiles -StudentNum $StudentNumber
}

答案1

问题在于 的一个尴尬行为Copy-Item。如果您通过管道传递一个空/null 集合(例如来自Get-ChildItem),它不会出错。与您可能预期的不同,因为管道确实$null会引发错误:

Get-ChildItem './MySrc' -Filter 'BadFilter' | Copy-Item ./MyDst  ## No Error
$Null | Copy-Item ./MyDst  ## Does Error

If (Test-Path){}对于文件,我更喜欢像Try/这样的结构,Catch以便在尝试更改之前确保路径等仍然有效:

# Check if file exists in correct path and copy,
If (Test-Path "$CurrentDir\$_") {
  Copy-Item -Force -Path "$CurrentDir\$_" -Destination .\marking
}

# Otherwise check recursively for the correct file and show a warning if found
ElseIf (Get-ChildItem -Path $CurrentDir -File -Recurse -Filter "$_") {
  Write-Warning "$StudentNumber did not follow the specified folder convention, but all files were submitted."
  Get-ChildItem -Path $CurrentDir -File -Recurse -Filter "$_" |
    Copy-Item -Force -Destination .\marking
}

# Error out if file not found
Else { 
  Write-Error -Message "$StudentNumber did not submit any of: $DoneFiles." -Category InvalidData
  Read-Host -Prompt "Press Enter to continue"
}

相关内容