2015-01-20 4 views
1

배치 파일을 사용하여 순차적으로 번호가 매겨진 특정 폴더 (0,1,2, ...)의 모든 파일을 유지하려고합니다. 이렇게하려면 먼저이 시퀀스에서 가장 높은 숫자가 무엇인지 파악해야합니다. 그러면 목록의 끝에 순차적으로 이름이 지정되지 않은 파일을 추가 할 수 있습니다. 예를 들어, 나는 다음과 같은 파일이있을 수 있습니다 :배치 파일을 사용하여 가장 높은 파일 이름을 순서대로 확인하는 가장 빠른 방법은 무엇입니까?

0.png

1.JPG

2.JPG

3.png

file_51.jpg

pictureabc .png

이렇게하면 결과가 3이므로 결과가 las입니다. t 파일 이름. 그러면 나머지 파일 (가장 좋은 방법 중 하나는 확실하지 않음)을 찾아 4에서 시작하는 번호를 매길 수 있습니다.

내가 지금까지 생각해 낸 유일한 해결책은 멈추는 무한한 고토 루프를 사용하는 것입니다. 해당 번호를 포함하는 파일 이름이없는 경우

set count=0 
:loop 
if exist %count%.* set /a count+=1 & goto loop 

이 솔루션은 매우 비효율적이지만 10 만 개의 이미지에 대해서는 거의 1 분이 걸립니다. 나는 가능한 한 10 초 이내에 이것을 달성 할 수있는 해결책을 찾고있다.

답변

0
@echo off 
    setlocal enableextensions disabledelayedexpansion 

    setlocal enabledelayedexpansion 
    set "nextFile=0" & for /f "delims=" %%a in (' 
     dir /a-d /b ^| findstr /b /r /x 
         /c:"[1-9][0-9]*\.[^.]*" 
         /c:"[1-9][0-9]*" 
         /c:"0" 
    ') do if %%~na geq !nextFile! set /a "nextFile=%%~na+1" 
    endlocal & set "nextFile=%nextFile%" 

    echo Next file will be: %nextFile% 

이것은 단지 숫자 만 이름을 가진 사람을 얻으려면 findstr으로 필터링 된 모든 파일의 목록을 검색 할 dir 명령을 사용합니다. 나머지는 파일 이름을 이전 최대 값과 비교하는 것입니다.

편집 -이 충분히 빨리

@if (@This === @IsBatch) 
@echo off 
    rem Start of batch zone ---------------------------------------------- 
    setlocal enableextensions disabledelayedexpansion 

    for /f %%a in (' 
     dir /a-d /b /o-d 
     ^| findstr /r /x /c:"[0-9][0-9]*\.[^.]*" /c:"[0-9][0-9]*" 
     ^| cscript //nologo //e:jscript "%~f0" 
    ') do set "nextFile=%%a" 

    echo next file will be %nextFile% 

    exit /b 
@end 
    // Start of JScript zone --------------------------------------------- 
    var inputStream = WScript.StdIn; 
    var max = 0, value ; 
    while(!WScript.StdIn.AtEndOfStream) { 
     value = parseInt(inputStream.ReadLine().split('.')[0], 10); 
     if (value >= max) max = value + 1; 
    } 
    WScript.StdOut.WriteLine(max);   

이는 하이브리드 배치/JScript를 파일로 작동합니다. .cmd 파일로 저장되면 dir 명령을 사용하여 파일 목록을 검색하고 findstr은 번호가 지정된 파일 만 남기고 원시 JScript 엔진은 숫자를 추출하고 가장 큰 값을 검색합니다.

@echo off 
setlocal EnableDelayedExpansion 
set lastNum=0 
for /L %%a in (1,1,9) do (
    for %%b in (%%a*.*) do (
     if %%~Nb gtr !lastNum! (
     set lastNum=%%~Nb 
    ) 
    ) 
) 
echo Last numbered file: %lastNum% 

편집 :

+0

이것은 또한 불행히도 goto 접근법보다 약간 오래 걸립니다. 이는 놀랍습니다. 어쨌든 도움을 주셔서 감사합니다. – Jimpi27

+0

@ Jimpi27, 예, 오늘 아침에 처리중인 이미지의 숫자를 인식하고 대답을 다시 평가하기 시작했습니다. 파일 목록에 구멍이 있거나 파일이 누락되었을 가능성이 있습니까? –

+0

@MC_ND 예 누락 된 번호는이 프로그램에서 확인하기를 바라는 부분 중 일부입니다. 나는 또한 디렉토리에서 파일을 생성, 삭제 또는 이름 변경하는 것과 같은 여러 이벤트에 대해 별도의 배치 파일을 만들 것입니다. 이 배치 파일은 모두 백그라운드에서 실행되는 C# 프로그램의 FileSystemWatcher에 의해 실행됩니다. – Jimpi27

0

나는이 가장 빠른 방법이라고 생각 새로운 방법이 추가

이전 방법은 존재하지 않는 파일의 수에 따라 달라집니다, 그래서 나는 최대한 빨리하지 않습니다 예상 ...

아래의 새로운 방법은 파일 수에 관계없이 거의 동일한 시간이 걸립니다.

@echo off 
setlocal EnableDelayedExpansion 
set "names=" 
for /L %%i in (1,1,9) do set "names=!names! %%i*.*" 
dir /B /A-D /O-D %names% 2> NUL | (set /P "lastNum=" & set lastNum) > lastNum.txt 
for /F "tokens=2 delims==." %%a in (lastNum.txt) do set "lastNum=%%a" 
del lastNum.txt 
echo Last numbered file: %lastNum% 

이전 방법 마지막 파일 중 두 개 이상의 파일이 생성 된 시간이 같으면 필요하지만이 지점은 필요할 경우 고정 될 수 있습니다.

+0

이것은 내가하고 싶은 것보다 더 좋아 보이지만 불행히도 원래의 방식보다 약 50 % 더 오래 걸립니다. – Jimpi27

+0

작전! 당신 말이 맞습니다 (당신의 방법이 파일 목록의 첫 번째 "구멍"에서 멈추더라도). 내 대답에 새로운 방법을 추가했습니다 ... – Aacini