通过检测同名的源目录和文件将多个文件合二为一 - PowerShell

Combine multiple files into one by detecting source directories and files with the same names - PowerShell

我是 PowerShell 新手。

目标

将嵌套 YAML 文件中的文本合并到主 YAML 文件中。

当前设置

文件结构

folder2/toc.yml

的内容
- name: JSON 1
  href: 1.json
- name: JSON 2
  href: 2.json

folder3/toc.yml 的内容

- name: JSON 3
  href: 3.json
- name: JSON 4
  href: 4.json

想要的结果

文件结构

根目录下 restapi 文件夹中 toc.yml 文件的内容

- name: JSON 1
  href: 1.json
- name: JSON 2
  href: 2.json
- name: JSON 3
  href: 3.json
- name: JSON 4
  href: 4.json

folder2/restapi/toc.yml和folder3/Docs/restapi/toc.yml不需要删除。

尝试的代码

$subfolderslist = (Get-ChildItem $PSScriptRoot -recurse | Where-Object { $_.PSIsContainer -eq $True -and $_.Name -like "restapi"} | Sort-Object)

foreach ($restapifolder in $subfolderslist) {
    $fullPath = $restapifolder.FullName
    $item = (Get-ChildItem $fullPath)
    Get-Content $fullPath/$item | Out-File -append $PSScriptRoot/restapi/toc.yml
}

这成功地在根目录下的 restapi 文件夹中生成了所需的附加内容。

但它出错了:Get-Content : Cannot find path 'C:\my-project\restapi.json 2.json 3.json toc.yml' because it does not exist.

我已尝试将 -Exclude *.json 添加到 $item 变量,但它 returns 对于 folder2 和 folder3 也是一个错误。示例:Get-Content : Cannot find path 'C:\myproject\folder3\Docs\restapi\C:\myproject\docs-multi-3\Docs\restapi\toc.yml' because it does not exist.

我也曾尝试排除 Where-Object 内根目录下的 restapi 文件夹,但同样失败。

我尝试了各种改变变量的方法。

这可能无关紧要,但就其价值而言,此脚本将在包含这些文件夹结构的存储库被克隆后在 Azure DevOps YAML 管道中执行(例如,folder2 是一个存储库,folder3 是一个存储库,等等) .

感谢您提供的任何帮助,包括有关完成此任务的更好方法的建议。

这就是我个人的做法,我创建了一个测试用例,这样您就可以看到所有的操作。我建议您先创建一个临时文件夹,然后 cd 到该临时文件夹,然后 运行 脚本来测试它是否在做您需要的事情。

# Create test case
$yaml1 = @'
- name: JSON 1
  href: 1.json
- name: JSON 2
  href: 2.json
'@

$yaml2 = @'
- name: JSON 3
  href: 3.json
- name: JSON 4
  href: 4.json
'@

$null = New-Item restapi -ItemType Directory -Force

foreach($i in 1..3)
{
    $path = [System.IO.Path]::Combine("folder$i", "Docs", "restapi")
    $ymlPath = Join-Path $path -ChildPath 'toc.yml'
    if($i -eq 2) {
        $null = New-Item $path -ItemType Directory -Force
        $yaml1 | Set-Content $ymlPath
        continue
    }
    if($i -eq 3) {
        $null = New-Item $path -ItemType Directory -Force
        $yaml2 | Set-Content $ymlPath
        continue
    }
    $null = New-Item "folder$i" -ItemType Directory -Force
}

# Logic
$destination = Get-Item ./restapi
$filePath = Join-Path $destination -ChildPath toc.yml
$mergedYaml = Get-ChildItem . -Recurse -Filter *.yml | Sort-Object {
    # Sort the Yaml files starting from the first numbered folder
    # "$_.Directory.Parent.Parent" would be the numbered folders (folder1, folder2, etc..)
    [int][regex]::Match($_.Directory.Parent.Parent, '\d+').Value
} | Get-Content -Raw
$mergedYaml | Set-Content $filePath
Get-Content $filePath