我有多个具有以下名称的文件夹:
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
。
如何获取数量最多的文件夹?
答案 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
的数字被解释为八进制数字,这意味着08
,09
,18
,19
等是无效的八进制数字,并且因此,在进行整数比较时,命令 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