Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Проверка последовательности в файлах. (http://forum.oszone.net/showthread.php?t=260669)

subuday77 16-05-2013 14:55 2151034

Проверка последовательности в файлах.
 
Здравствуйте! Есть такая задача:
В некой папке есть файлы. Имена файлов - порядковый набор цифр. Расширение - буква и две цифры. Нужно проверить, идут ли файлы подряд или некоторых не хватает. Например:

12345001.В12
12345002.В12
12345004.В12

Не хватает 12345003.В12

Вторая беда в том, что расширения могут быть разными, соответственно номера файлов могут повторяться. Например:

12345001.В10
12345001.В12
12345002.В10
12345002.В12
12345003.В10
12345004.В10
12345004.В12

Всё ещё не хватает 12345003.В12

В принципе, можно руками вводить номер, с которого начинать проверять и расширение. Но я всё равно не знаю, как проверить, что оно идёт попорядку.

Зарание благодарен за любую помощь!

Iska 16-05-2013 17:14 2151113

subuday77, приведите пример имён реальных файлов: важно увидеть длину и выделить постоянную часть.

kiripanda 16-05-2013 17:23 2151116

http://wincmd.ru/plugring/seq_wfx.html

subuday77 16-05-2013 21:31 2151256

Iska, Оно так и выглядит. Первые 5 цифр номер лицензии, 3 цифры - номер архива, расширение показывает, с какого сервера файл. Собственно в одном массиве первые 5 цифр чаще всего одинаковыми, кроме случаев, когда на одной машине работают несколько клиентов. Но длина имени всегда 5+3 . 3

kiripanda, спасибо, но не вариант. Проверка выпоняется на машинах клиентов.

Georgio 17-05-2013 03:13 2151354

subuday77, для двух расширений файлов:

Код:

@ECHO OFF
SET Folder=E:\Work\
SET Extension_1=.‚10
SET Extension_2=.‚12
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=1 delims=." %%I IN ('DIR %Folder% /B /O:N') DO (
SET Name=%%I
GOTO #
)
:#
FOR /F "tokens=1 delims=." %%I IN ('DIR %Folder% /B /O:N') DO (
  SET /A Skip=%%I-!Name!-1
  IF !Skip! GEQ 1 (
    FOR /L %%K IN (1,1,!Skip!) DO (
    SET /A Missing_File=!Name!+%%K
    ECHO !Missing_File!%Extension_1%
    ECHO !Missing_File!%Extension_2%
)
  IF NOT EXIST %Folder%%%I%Extension_1% ECHO %%I%Extension_1%
  IF NOT EXIST %Folder%%%I%Extension_2% ECHO %%I%Extension_2%
  SET Name=%%I
) ELSE (
  IF NOT EXIST %Folder%%%I%Extension_1% ECHO %%I%Extension_1%
  IF NOT EXIST %Folder%%%I%Extension_2% ECHO %%I%Extension_2%
  SET Name=%%I
))
PAUSE>nul


Iska 17-05-2013 05:26 2151361

Цитата:

Цитата subuday77
Iska, Оно так и выглядит. Первые 5 цифр номер лицензии, 3 цифры - номер архива, расширение показывает, с какого сервера файл. Собственно в одном массиве первые 5 цифр чаще всего одинаковыми, кроме случаев, когда на одной машине работают несколько клиентов. Но длина имени всегда 5+3 . 3 »

subuday77, Вам как удобнее задавать потребную папку, постоянную часть имени («Первые 5 цифр номер лицензии») и расширение («расширение показывает, с какого сервера файл») — будете менять непосредственно в теле пакетного файла, будете задавать параметрами пакетного файла, будете вводить в ответ на запрос пакетного файла?

Можно, например, перетаскивать какой-либо файл (из набора потребных для проверки) на пакетный файл, а пакетный файл по переданному имени уже сам будет определять папку, постоянную часть имени и расширение, иначе — запрашивать то. другое и третье в диалоге:
читать дальше »
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

set sFullFileName=%~1

if defined sFullFileName (
        set sFolder=%~dp1
        set sTempValue=%~n1
        set sConstPart=!sTempValue:~0,5!
        set sExt=%~x1
) else (
        set /p sTempValue=Enter folder name:
        set sFolder=!sTempValue!\
        set /p sConstPart=Enter constant part of file name:
        set /p sTempValue=Enter extension of file name:
        set sExt=.!sTempValue!
)

if exist "%sFolder%." (
        for /l %%i in (999, -1, 1) do (
                set sPattern=000%%i
                set sFileName=%sConstPart%!sPattern:~-3!%sExt%
               
                if exist "%sFolder%!sFileName!" if not defined sLastIndex set sLastIndex=%%i
        )

        if defined sLastIndex (
                for /l %%i in (1, 1, !sLastIndex!) do (
                        set sPattern=000%%i
                        set sFileName=%sConstPart%!sPattern:~-3!%sExt%
                       
                        if not exist "%sFolder%!sFileName!" echo !sFileName!
                )
        ) else (
                echo Not found any file in folder [%sFolder%] by pattern [%sConstPart%xxx%sExt%].
        )
) else (
        echo Folder [!sFolder!] not found.
)
       
pause

endlocal
exit /b 0


Georgio 17-05-2013 13:11 2151508

subuday77, вот простой и почти универсальный вариант:

Код:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET Folder=E:\Work
SET n=0
FOR /F "tokens=2 delims=." %%I IN ('DIR "%Folder%" /B /O:E') DO IF NOT "%%I"=="!Extension!" SET Extension=%%I&&SET /A n=!n!+1&&SET Extension_!n!=%%I
SET Max_Name=0
FOR %%I IN ("%Folder%\*") DO IF %%~nI GEQ !Max_Name! SET Max_Name=%%~nI
SET Min_Name=!Max_Name!
FOR %%I IN ("%Folder%\*") DO IF %%~nI LEQ !Min_Name! SET Min_Name=%%~nI
FOR /L %%I IN (!Min_Name!,1,!Max_Name!) DO FOR /F "tokens=2 delims==" %%J IN ('SET Extension_') DO IF NOT EXIST "%Folder%\%%I.%%J" ECHO %%I.%%J
PAUSE>nul

В качестве рабочей переменной задаётся только каталог. Число расширений и длина имени файла не лимитированы. Необходимо только, чтобы в имени файла были только цифры без нулей в начале.

subuday77 17-05-2013 17:09 2151643

Iska, Georgio, спасибо! В воскресенье выйду на работу, буду пробовать.

megaloman 17-05-2013 21:49 2151775

Цитата:

Цитата subuday77
Первые 5 цифр номер лицензии, 3 цифры - номер архива, расширение показывает, с какого сервера файл. Собственно в одном массиве первые 5 цифр чаще всего одинаковыми, кроме случаев, когда на одной машине работают несколько клиентов. Но длина имени всегда 5+3 . 3

Вот решение, если имена файлов (первые 5 знаков) в папке возможны разные, при этом:

-имена файлов 5+3, где 5 знаков префикс, 3 знака номер,
-для каждого префикса могут быть свой набор расширений,
-начало и конец нумерации для каждого префикса может быть своя,
Код:

@Echo Off
cls
SetLocal EnableExtensions EnableDelayedExpansion

Set Where=E:\DDDDDDDDD\bbbb

Set Name=

FOR /F "usebackq delims=" %%n IN (`Dir "%Where%\*.*" /B /O:N`) DO (
        Set N=%%~nn
        Set NN1=1!N:~-3!
        Set N=!N:~0,5!
        If /I Not "!Name!"=="!N!" (
                Set Name=!N!
                Set NN2=""
                FOR /F "usebackq delims=" %%m IN (`Dir "%Where%\!Name!???.*" /B /O:-N`) DO If !NN2!=="" Set NN2=%%~nm
                Set NN2=1!NN2:~-3!

                Set Ext=
                FOR /F "usebackq delims=" %%m IN (`Dir "%Where%\!Name!???.*" /B /O:E`) DO (
                        If /I Not "!Ext!"=="%%~xm" (
                                Set Ext=%%~xm
                                FOR /L %%i IN (!NN1!,1,!NN2!) DO (
                                        Set FNo=%%i
                                        Set FNo="%Where%\!Name!!FNo:~-3!!Ext!"
                                        If Not Exist !FNo! Echo !FNo!
                                )
                        )
                )

        )
)

Вместо E:\DDDDDDDDD\bbbb пропишите свой путь без \ и БЕЗ ПРОБЕЛОВ в конце строки
Если нумерация в имени обязательно должна начинаться с 001,
читать дальше »
то вместо имеющегося надо написать цикл
Код:

FOR /L %%i IN (1001,1,!NN2!) DO (
хотя, в принципе, в этом случае батник можно упростить
читать дальше »
Код:

@Echo Off
cls
SetLocal EnableExtensions EnableDelayedExpansion

Set Where=E:\DDDDDDDDD\bbbb

Set Name=

FOR /F "usebackq delims=" %%n IN (`Dir "%Where%\*.*" /B /O:-N`) DO (
        Set N=%%~nn
        Set NN2=1!N:~-3!
        Set N=!N:~0,5!
        If /I Not "!Name!"=="!N!" (
                Set Name=!N!

                Set Ext=
                FOR /F "usebackq delims=" %%m IN (`Dir "%Where%\!Name!???.*" /B /O:E`) DO (
                        If /I Not "!Ext!"=="%%~xm" (
                                Set Ext=%%~xm
                                FOR /L %%i IN (1001,1,!NN2!) DO (
                                        Set FNo=%%i
                                        Set FNo="%Where%\!Name!!FNo:~-3!!Ext!"
                                        If Not Exist !FNo! Echo !FNo!
                                )
                        )
                )

        )
)


Foreigner 18-05-2013 12:48 2152000

Мой вариант
Код:

@echo off
setlocal

pushd "C:\test"

for /f %%i in ('dir /b') do set "ext_%%~xi=%%~xi"
for /f "tokens=2 delims==" %%i in ('set ext_') do call:1 "%%i"
popd
goto:eof

:1
for %%i in (*%~1) do if not defined min (set min=%%~ni) else (set max=%%~ni)
for /l %%i in (%min%,1,%max%) do if not exist %%i%~1 echo %%i%~1

for %%i in (min max) do set "%%i="


subuday77 19-05-2013 13:48 2152493

Спасибо всем, кто уже принял участие в этом проекте. К сожалению, всё, что мы попробовали до сих пор, "немножко не то"... Честно признаюсь, у меня не хватает мозгов, чтобы состряпать что-то путное, даже опираясь на предложенные вами коды. По-этому, я попытаюсь максимально подробно описать, что именно нужно.

1. Выбор директории.
Способ не важен. Drug & Drop, предложенный Iska, это хорошо, но не критично.
2. Список расширений.
В папке следует проверить, какие расширения присутствуют. Они всегда будут иметь следующий вид: H01 H02 H03 и и.д. Последний - H34, но возможен дальнейший рост, так что, если прописывать жёстско, то стоит дойти до H50.
3. Проверка файлов.
Для каждого расширения следует проверить, какой номер файла является максимальным. Имя файла состоит из двух частей. XXXXXYYY.HZZ, где XXXXX - номер лицензии, YYY - номер файла, а HZZ - расширение(указывает, с какого сервера файл). Тут можно запросить ввести номер лицензии вручную. Найдя максимальный номер для первого расширения, следует проверить наличие файлов, начиная с XXXXX001 и до максимального. Затем следует перейти к следующему расширению и повторить процедуру. (Без повторного запроса номера лицензии).
4. Отображение результатов.
Результаты хотелось бы в текстовой файл, в котором бы было указанно:
Номер лицензии
Список расширений
Если порядок не нарушен - расширение, первый и последний файлы и отметка, что всё в порядке.
Если порядок нарушен - расширение, первый и последний файлы и список недостающих файлов.

Как-то так. Если кто-то такое напишет - будем очень благодарны! Зарание спасибо за любую помощь!

Iska 19-05-2013 14:48 2152508

subuday77, учитесь сразу излагать условия ТЗ полностью.

Цитата:

Цитата subuday77
Они всегда будут иметь следующий вид: H01 H02 H03 и и.д. »

Пропуски в расширениях могут быть — «H01», «H02» и сразу, например, «H04» или «H25»?

Foreigner 19-05-2013 17:21 2152566

subuday77,
Код:

@echo off
setlocal

set /p dir="Choose Folder: "

pushd "%dir%" || echo Wrong Path && goto:eof

for /f "tokens=*" %%i in ('dir /b') do call:set "%%i"
for /f "tokens=2-4 delims=_=" %%i in ('set set_') do (

1>>"%~dp0report.txt" (

    echo.
    echo License: %%j
    echo --------------
    echo Extension: %%i:, Last number %%k
    echo.

)

    for /l %%l in (1001,1,1%%k) do call:check %%j %%l %%i
   
)

popd
goto:eof

:set

set "file=%~1"
set "set_%~x1_%file:~0,5%=%file:~5,3%"
goto:eof

:check

set "num=%2"
if not exist %1%num:~-3%%3 1>>"%~dp0report.txt" (echo    missing file: %1%num:~-3%%3)


Iska 19-05-2013 18:42 2152615

Цитата:

Цитата Foreigner
Код:

pushd "%dir%" || echo Wrong Path && goto:eof
»

Один «&»?!

Foreigner 19-05-2013 19:04 2152631

Цитата:

Один «&»?!
Тогда сразу закончит работу & -- выполняется независимо от errorlevel. Попробуй в консоли:
Код:

pushd C:\Windows || echo bad & exit

Iska 19-05-2013 20:20 2152670

Тогда так:
Код:

pushd "%dir%" || (echo Wrong Path & goto:eof)
Я последнее время совсем пространство не экономлю, пишу так:
Код:

pushd "%dir%" || (
    echo Wrong Path
    goto:eof
)

Жаль, не всегда внутри цикла интерпретатор команд разбирает такой афронт.

subuday77 19-05-2013 22:11 2152717

Iska,
Цитата:

Цитата Iska
Пропуски в расширениях могут быть — «H01», «H02» и сразу, например, «H04» или «H25»? »

Да. Набор файлов может выглядеть, на пример, так:

12345001.Н10
12345001.Н12
12345002.Н10
12345002.Н12
12345003.Н10
12345004.Н10
12345004.Н12

Не хватает 12345003.В12

Соответственно, результат дожен быть примерно такой:
Н10 12345001-12345004 No missing files
H12 12345001-12345004 12345003 is missing

Iska 20-05-2013 00:47 2152765

subuday77, хоть убейте, никак не могу понять, как в наборе:
Код:

12345001.Н10
12345001.Н12
12345002.Н10
12345002.Н12
12345003.Н10
12345004.Н10
12345004.Н12

может не хватать «12345003.В12».

subuday77 20-05-2013 14:37 2152984

Iska, опечатка! Простите.

Foreigner, похоже, работает! Спасибо огромное! Переходим к полевым испытаниям.


Время: 12:35.

Время: 12:35.
© OSzone.net 2001-