简体   繁体   English

Powershell:按版本号选择文件夹

[英]Powershell: choose folder by version number

I'm writing a PowerShell script that goes into a couple of folders and runs a .bat file inside said folders. 我正在写一个PowerShell脚本,它进入几个文件夹并在所述文件夹中运行.bat文件。 These folders are frequently updated and I only need to run the script from the newest folder of a certain type. 这些文件夹经常更新,我只需要从某种类型的最新文件夹运行脚本。

The folders look something like this: 文件夹看起来像这样:

Core_1.1.2
Core_1.3.4
Core_1.4.1
Extras_1.0.4
Extras_1.2.5
Extras_1.3.8
etc_1.1.2
etc_1.1.9
etc_1.2.6

Using the above folders as an example, I would need to go into Core_1.4.1 , Extras_1.3.8 , and etc_1.2.6 and run a file called run.bat which exists in each one of those directories. 以上面的文件夹为例,我需要进入Core_1.4.1Extras_1.3.8etc_1.2.6并运行一个名为run.bat的文件,该文件存在于每个目录中。

So what I would need is to find the highest version in Core_* , the highest version in Extras_* , etc. 所以我需要的是找到Core_*中的最高版本, Extras_*的最高版本等。

If there was some way to get an array of folder names with a specific prefix, then sort the elements of that array alphanumerically and return the last item in the array that would work perfectly. 如果有某种方法可以获得具有特定前缀的文件夹名称数组,则以字母数字方式对该数组的元素进行排序,并返回数组中可以完美运行的最后一项。 I'd like to stay away from choosing folder based on modification dates as that might be problematic. 我想远离根据修改日期选择文件夹,因为这可能会有问题。

There is a System.Version class which can help do the parsing and sorting for you. 有一个System.Version类,可以帮助您进行解析和排序。 This solves problems caused by comparing strings. 这解决了比较字符串引起的问题。 Comparing strings will result in lexicographic sorts where 1.10.0 is "lower" than 1.2.0. 比较字符串将导致词典排序,其中1.10.0“低于”1.2.0。 This not the typical order used when comparing version numbers. 这不是比较版本号时使用的典型顺序。 Something like this could work to find the newest "Core" folders: 这样的东西可以找到最新的“核心”文件夹:

$core = ls -Filter Core_* | sort { [version]($_.Name -replace '^.*_(\d+(\.\d+){1,3})$', '$1') } -Descending | select -Index 0

Then it just a matter of calling the bat file: 然后只需调用bat文件:

 & "$($core.FullName)\activate.bat"

My first idea would be something like this: 我的第一个想法是这样的:

$versions = { [int]($_.Name -replace '.*?_(\d+)\.(\d+)\.(\d+)', '$1') }, { [int]($_.Name -replace '.*?_(\d+)\.(\d+)\.(\d+)', '$2') }, { [int]($_.Name -replace '.*?_(\d+)\.(\d+)\.(\d+)', '$3') }

#Get folders
Get-ChildItem |
#Extract versions and sort highest first
Sort-Object $versions -Descending |
#Get first item/folder (highest version)
Select-Object -First 1


    Directory: C:\Users\Frode\Desktop\test


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        29.08.2014     18:43            Core_1.4.1  

I'll offer an alternative using a RegEx, Group, and some string combining. 我将使用RegEx,Group和一些字符串组合提供替代方案。

PS C:\Users> $Folders = Get-ChildItem $path -directory | Where{$_.name -match "(.+?_)(.*)$"} | ForEach{[pscustomobject]@{'base'=$matches[1];'version'=$matches[2]}} | group base | ForEach{($_.Name)+($_.group|select -last 1 -ExpandProperty version)}

PS C:\Users> $Folders 
Core_1.4.1
Extras_1.3.8
BP_1.2.6

PS C:\Users> $Folders | ForEach{& "$path\$_\BatchFile.bat"}

Edit: I love how people mark down things but don't bother to comment as to why they marked them down. 编辑:我喜欢人们如何记下事情但却不愿意评论他们为什么将其标记下来。 My answer is functional for the OP's purposes. 我的答案对于OP的目的是有用的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM