如何获得文件夹名称中编号最高的文件夹名称?

时间:2019-12-16 06:42:57

标签: powershell batch-file

我有多个具有以下名称的文件夹:

ABC_03_00_016_0
ABC_03_00_016_1
ABC_03_00_016_2
ABC_03_00_016_3
ABC_03_00_016_4
ABC_03_00_016_5

我想做的是使用PowerShell或批处理命令在文件夹名称的末尾保留编号最大的文件夹,即ABC_03_00_016_5

如何获取数量最多的文件夹?

5 个答案:

答案 0 :(得分:0)

也许这可以做得更优雅,但是它可以按您的意愿工作。我正在剥离最后一个数字,进行转换和比较,然后确定最高的数字。如您所见,顺序并不重要:

$items = 
"ABC_03_00_016_0",
"ABC_03_00_016_100",
"ABC_03_00_016_99"

[int]$highestNumberTillNow = 0
$highestitem = ""
foreach ($item in $items){
    [int]$number = $item.substring($item.LastIndexOf("_")+1,$item.length-$item.LastIndexOf("_")-1)
    if ($number -gt $highestNumberTillNow){
        $highestNumberTillNow = $number
        $highestitem = $item
    }
}
write-host $highestitem

答案 1 :(得分:0)

仅当所有文件夹名称都具有相同的长度时才可以使用第一种方法,即,使用前导零来确保所有文件夹名称中的所有数字都具有相同的数字。

@echo off
set "LastFolder="
for /F "eol=| delims=" %%I in ('dir "%~dp0ABC_03_00_016_*" /AD /B /O-N 2^>nul') do set "LastFolder=%%I" & goto HaveFolder
echo Found no folder matching pattern ABC_03_00_016_* in "%~dp0".
goto :EOF

:HaveFolder
echo Last folder according to sorted folder names is: %LastFolder%

获取最后一个数字最大的文件夹名称的任务比较困难,因为最后一个数字不同。

@echo off
set "LastFolder="
setlocal EnableExtensions EnableDelayedExpansion
set "FolderNumber=-1"
for /F "eol=| delims=" %%I in ('dir "%~dp0ABC_03_00_016_*" /AD /B 2^>nul') do (
    for /F "eol=| tokens=5 delims=_" %%J in ("%%I") do (
        if %%J GTR !FolderNumber! (
            set "LastFolder=%%I"
            set "FolderNumber=%%J"
        )
    )
)
endlocal & set "LastFolder=%LastFolder%"

if not defined LastFolder (
    echo Found no folder matching pattern ABC_03_00_016_* in "%~dp0".
) else (
    echo Last folder according to last number in name is: %LastFolder%
)

注意:使用上面的第二个代码时,文件夹名称中的最后一个数字不应以零开头。具有一个或多个前导0的数字被解释为八进制数字,这意味着08091819等是无效的八进制数字,并且因此,在进行整数比较时,命令 IF 将其解释为值0。在 IF 条件上方将需要其他代码,以便在进行整数比较之前首先从数字字符串中删除所有前导0

要了解所使用的命令及其工作方式,请打开command prompt窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。

  • call /? ...说明%~dp0(批处理文件的驱动器和路径以反斜杠结尾)。
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • if /?
  • set /?
  • setlocal /?

阅读有关Using command redirection operators的Microsoft文章,以获取2>nul的解释。当Windows命令解释器在执行命令之前处理此命令行时,重定向操作符>必须在 FOR 命令行上使用脱字符号^进行转义,才能被解释为文字字符。 FOR ,它将在后台启动的单独命令进程中执行嵌入式dir命令行。

答案 2 :(得分:0)

您可以使用此:

@echo off
setlocal enabledelayedexpansion 
pushd "%~dp0"
for /f "tokens=4 delims=_" %%a in ('dir ABC_03_016_* /ad /b') do (
  for /f "tokens=* delims= " %%b in ('dir ABC_03_016_* /ad /b') do (
    set dir[%%a]=%%b
  )
)
set dc=0
:loop
set /a dc=dc+1
if defined dir[%dc%] goto loop
goto break
:break
set /a dc=dc-1
echo The folder is !dir[%dc%]!
pause >nul

答案 3 :(得分:0)

假设您可以在根路径中拥有更多名称相似的文件夹,例如

ABC_03_00_016_0
ABC_03_00_016_1
ABC_03_00_016_2
ABC_03_00_016_3
ABC_03_00_016_4
ABC_03_00_016_5
DEF_03_00_016_0
DEF_03_00_016_1
DEF_03_00_016_10

使用PowerShell,您可以使用类似下面的内容。 这将返回名称末尾编号最高的文件夹对象:

$lastFolder = Get-ChildItem -Path 'D:\test' -Directory | Where-Object { $_.Name -match '(.+)_(\d+)$' } |
    Group-Object -Property @{Expression={ $matches[1] }}  | ForEach-Object {
        $_.Group | Sort-Object -Property @{Expression={ [int]$matches[2] }} | Select-Object -Last 1
    }

# for demo, just output the FullName property of the folders found
$lastFolder.FullName

输出:

D:\test\ABC_03_00_016_5
D:\test\DEF_03_00_016_10

正则表达式详细信息:

(            Match the regular expression below and capture its match into backreference number 1
   .         Match any single character that is not a line break character
      +      Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
_            Match the character “_” literally
(            Match the regular expression below and capture its match into backreference number 2
   \d        Match a single digit 0..9
      +      Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
$            Assert position at the end of the string (or before the line break at the end of the string, if any)

答案 4 :(得分:0)

如果您要删除除以最大编号结尾的目录之外的所有目录,那么我也建议使用PowerShell:

Get-ChildItem -Path 'C:\Users\Naqqash\Desktop' -Filter '*_*_*_*_*' -Directory |
  Where-Object { $_.Name -Match '(.+)_(\d+)$' } |
    Sort-Object -Property { [Int]$($_.Name).Split('_')[-1] } |
      Select-Object -SkipLast 1 |
        Remove-Item

请记住将第一行的路径调整为保存目录的路径。

上面的示例需要PowerShell v5.0