Войти

Показать полную графическую версию : [решено] Батник для сравнения файлов


Страниц : [1] 2

orgia
13-02-2013, 12:34
Всем привет!

Оч нужна ваша помощь.

Нужен батник для сравнения 2 х файлов по содержимому. Например с фтп копирую файлы, например в с:\tmp\, его копия копируется в архив. Например если в какой нибудь файлик в с:\tmp кто нибудь внес изменения, цифры например поменял или текст какой, то этот файлик нужно переместить в папку c:\error, а другие файлы переместить в папку с:\in и так циклически.

Заранее благодарю!!!

megaloman
14-02-2013, 09:49
Для этого существует команда fc
Синтаксис команды можно посмотреть fc /?
При отсутствии различий в файлах она возврвщает ErrorLevel=0, что можно потом проанализировать и предпринять дальнейшие действия.@echo off
cls
fc /B 1.txt 2.txt >nul
Echo %ErrorLevel%

Iska
15-02-2013, 03:07
fc /B 1.txt 2.txt >nul 1>nul 2>nul »
Зачем дважды перенаправляете stdout?

orgia
15-02-2013, 06:09
Спасибо за помощь, мне нужно сравнить ряд файлов в этих папках, туда сваливаю несколько файлов разных одновременно и сравнивать надо те что на с:\tmp\ c другими которые в архиве. В случае несовпадения одного файла из нескольких, этот файл нужно в еррор свалить а которые не изменились оставить. Я пробовал с помощью программы comp.exe. Она сравнивает их корректно, но я не могу применить результат.

megaloman
15-02-2013, 19:55
orgia, Я понял так, что сравнивать надо файл в TMP и файл с таким же именем в архиве? Это можно сделать так @echo off

Set TmpFtp=D:\Tmp
Set TmpArc=D:\TmpArc
Set TmpErr=D:\TmpErr
Set TmpIn=D:\TmpIn

SetLocal EnableExtensions EnableDelayedExpansion

FOR %%f IN (%TmpFtp%\*.*) DO (
fc /B "%%f" "%TmpArc%\%%~nxf" >nul
If !ErrorLevel!==0 (
Move /Y "%%f" "%TmpIn%\" >nul
) Else (
Move /Y "%%f" "%TmpErr%\" >nul
)
)
Я не рассматривал случай отсутствия файла в архиве, так как Например с фтп копирую файлы, например в с:\tmp\, его копия копируется в архив
Если файла в архиве нет, то из TMP он свалится в Err.
Или Вам надо каждый файл в tmp сравнить со всеми файлами в архиве и найти / не найти совпадение?

Iska, Не стреляйте в пианиста, он играет, как умеет. Уровень Ваших знаний выше. Спасибо за помощь

orgia
15-02-2013, 20:22
Если файла в архиве нет, то из TMP он свалится в Err.
Или Вам надо каждый файл в tmp сравнить со всеми файлами в архиве и найти / не найти совпадение? »
Во первых, спасибо за содействие.
Файлы копируются из одного места в 2 разных папки. У меня есть требование перед обработкой их на c:\tmp проверить на идентичность их в архиве. И только после сравнения кидать на обработку. Как то так.

Iska
16-02-2013, 05:08
Iska, Не стреляйте в пианиста, он играет, как умеет. Уровень Ваших знаний выше.»
Я бы так не сказал, коллега ;).

orgia
16-02-2013, 10:44
спасибо, но он некорректно работат. при 2х одинаковых файлах в in не переносит.
пишет достигнут уровень рекурсии, максимальный возможный для данной команды setlocal
и на этом все.

Tco 03
16-02-2013, 11:07
megaloman
Очень хороший код, как раз то, что я искал! А возможно ли создать папки автоматически? То есть в папке Tmp находятся не только файлы, но ещё и другие файлы в подпапках. И создать точно такую же структуру папок, в папках: TmpArc, TmpErr, TmpIn, и потом удалить все папки (с подпапками (вместе с файлами)), кроме папки: TmpErr
Ну или на крайний случай, как создать структуру папок мануально и потом их удалить? Сорри если туплю - я не силён в написании bat-ников.

megaloman
16-02-2013, 11:26
orgia, Что делает моё решение:
Сравнивает файл из D:\Tmp с одноименным файлом в архиве D:\TmpArc.
Если файлы совпадают, перемещаю файл из D:\Tmp в D:\TmpIn
Иначе в папку D:\TmpErr
И так циклически. Еще раз проверил - работает, переносит всё куда надо в зависимости от совпадения/несовпадения. Возможно, Вы некорректно указываете пути в батнике - самая распространённая проблема, когда в определении пути в конце имеются пробелы. Для отладки попробуйте вариант@echo on
cls

SetLocal EnableExtensions EnableDelayedExpansion

FOR %%f IN (D:\Tmp\*.*) DO (
fc /B "%%f" "D:\TmpArc\%%~nxf"
If !ErrorLevel!==0 (
Move /Y "%%f" "D:\TmpIn\"
) Else (
Move /Y "%%f" "D:\TmpErr\"
)
pause
) Проанализируйте, есть ли там сообщения об ошибках. Сообщите.

И вообще, смысл задачи ускользает.
В норме у Вас пара файлов с одинаковыми именами в тмп и архиве, в норме они идентичны.
В тмп пользователь может изменить файл, в архиве - эталон.
Если в тмп пришел файл, одновременно он пришел и в архив (по условию Вашей задачи)
Нам всё равно, что творится с содержимым файла в тмп, главное, пришел файл, его надо обработать, и файл для обработки будем копировать в Ин из архива (где заведомо правильный файл). А в ТМП файл просто удаляем. Смысла сравнивать файлы вообще не вижу.

Tco 03, Возможно. Но мне надо четкая постановка.

orgia
16-02-2013, 11:39
Кинул один и тот же файл в c:\Tmp и в c:\TmpArc.

Вот результат.
По факту файлы остались на старых местах.

Левая Файлы Команды Параметры Правая 14:36
C:\>SetLocal EnableExtensions EnableDelayedExpansion
Достигнут уровень рекурсии, максимально возможный для команды SETLOCAL.

C:\>FOR %f IN (C:\Tmp\*.*) DO (
fc /B "%f" "C:\TmpArc\%~nxf"
If !ErrorLevel! == 0 (Move /Y "%f" "C:\TmpIn\" ) Else (Move /Y "%f" "C:\TmpErr
\" )
pause
)


При вторичном запуске вот так:
файл почему то переместился в tmperr

C:\>SetLocal EnableExtensions EnableDelayedExpansion
Достигнут уровень рекурсии, максимально возможный для команды SETLOCAL.

C:\>FOR %f IN (C:\Tmp\*.*) DO (
fc /B "%f" "C:\TmpArc\%~nxf"
If !ErrorLevel! == 0 (Move /Y "%f" "C:\TmpIn\" ) Else (Move /Y "%f" "C:\TmpErr
\" )
pause
)

C:\>(
fc /B "C:\Tmp\FarMenu.ini" "C:\TmpArc\FarMenu.ini"
If !ErrorLevel! == 0 (Move /Y "C:\Tmp\FarMenu.ini" "C:\TmpIn\" ) Else (Move /Y
"C:\Tmp\FarMenu.ini" "C:\TmpErr\" )
pause
)
Перемещено файлов: 1.
Для продолжения нажмите любую клавишу . . .
Не удается найти указанный файл.
Для продолжения нажмите любую клавишу . . .
Не удается найти указанный файл.
Для продолжения нажмите любую клавишу . . .














C:\>

Tco 03
16-02-2013, 12:13
Возможно. Но мне надо четкая постановка. »
В папку Tmp и TmpArc кладём не только файлы, но ещё и другие папки с файлами. То есть папки будут иметь структуру Tmp\Folder1, Tmp\Folder2\Folder3, TmpArc\Folder1, TmpArc\Folder2\Folder3 Задача: проанализировать все папки включая подпапки, не указывая путь к ним: Set TmpFtp=D:\Tmp , а анализировать все подпапки в текущем каталоге: Set TmpFtp=.\Tmp, Set TmpArc=.\TmpArc При совпадении файлов, фалы переносятся в: .\TmpIn и если файлы находятся ещё в подпапке, то папки создаются автоматически: TmpIn\Folder1, TmpIn\Folder1\Folder2 и файлы переносятся в эту папку. Анолагично и с: TmpErr
Такое возможно?

megaloman
16-02-2013, 13:22
orgia, Мне не удалось повторить Вашу ситуацию, было бы полезным получить от Вас живые файлы. Попробуйте вариант @echo off

Set TmpFtp=D:\Tmp
Set TmpArc=D:\TmpArc
Set TmpErr=D:\TmpErr
Set TmpIn=D:\TmpIn

FOR %%f IN (%TmpFtp%\*.*) DO Call :CompMove "%%f" "%TmpArc%\%%~nxf"
GoTo :Eof

:CompMove

If Not %~z1==%~z2 (
Move /Y %1 "%TmpErr%\" >nul
GoTo :Eof
)

fc /B %1 %2 >nul

If %ErrorLevel%==0 (
Move /Y %1 "%TmpIn%\" >nul
) Else (
Move /Y %1 "%TmpErr%\" >nul
)
Я, кроме того, сделал решение более эффективным. При сравнении больших отличающихся файлов команда fc работает долго. Я сделал предварительный контроль длины файла. Если длины файлов не совпадают - значит они разные. Если не получится и с этим решением, сделайте для отладки Echo On, уберите перенаправления вывода >nul и просмотрите ошибочные сообщения. До возможной причины аварийного сообщения в предыдущем решении пока не докапывался, такое ощущение, что моё решение находится внутри внешнего цикла другого батника.

megaloman
16-02-2013, 16:05
Tco 03, Ваше второе сообщение не очень коррелирует с первым. Итак решение ИМХО с условием, совпадающем с предыдущим (как я его понял во втором сообщении):
Есть папка Tmp и TmpArc.
Сравниваем файл из D:\Tmp с одноименным файлом в архиве D:\TmpArc.
Если файлы разные или в D:\TmpArc его нет, то из D:\Tmp перемещаем файл в D:\TmpErr
Если файлы одинаковые, то перемещаем в D:\TmpIn
Единственное отличие, файлы могут содержаться в поддиректориях и при перемещении структуру директорий надо сохранить.@echo off

FOR /R "D:\Tmp" %%f IN (*.*) DO Call :Files "%%f"
GoTo :Eof

:Files

Set TmpFtp=%1
Set TmpArc=%TmpFtp:D:\Tmp=D:\TmpArc%

Set TmpFtp=%~dp1
Set TmpErr=%TmpFtp:D:\Tmp=D:\TmpErr%
Set TmpIn=%TmpFtp:D:\Tmp=D:\TmpIn%


Call :CompMove %1 %TmpArc%
GoTo :Eof

:CompMove

Set L=1
If Not Exist %2 Set L=0
If %L% EQU 1 If Not %~z1==%~z2 Set L=0
If %L% EQU 0 (
If Not Exist %TmpErr% Md %TmpErr%
Move /Y %1 %TmpErr% >nul
GoTo :Eof
)

fc /B %1 %2 >nul

If %ErrorLevel%==0 (
If Not Exist %TmpIn% Md %TmpIn%
Move /Y %1 %TmpIn% >nul
) Else (
If Not Exist %TmpErr% Md %TmpErr%
Move /Y %1 %TmpErr% >nul
) Аккуратно замените мои пути D:\Tmp D:\TmpArc D:\TmpErr D:\TmpIn на свои в коде

orgia, В личном сообщении Вы писали Может имеет значение что у мну стоит win7 64x? Я по пооду отработки первого варианта пакетника?
А второй пишет, что не найден пакетный файл CompMove У меня нет в близком доступе такой системы, не берусь вникнуть в эту проблему. Обнародовал личное сообщение в надежде, что кто-то более сведущий сможет Вам помочь.

Tco 03
16-02-2013, 16:53
megaloman Ваше второе сообщение не очень коррелирует с первым. »
Это просто уже другая мысль, на предыдущее сообщение я не смотрел... Всё верно! Работает как надо! Только как сделать это всё в текущем каталоге, т.е. там, где находиться сам bat-ник? С предыдущим примером - всё просто:
Set TmpFtp=.\Tmp
Set TmpArc=.\TmpArc
Set TmpErr=.\TmpErr
Set TmpIn=.\TmpIn
Вот со вторым... Просто мне (желательно нужно) чтобы он работал в самой папке, а не до пути к букве диска. Ну ето уже не так уж важно. В любом случаи благодарю за помощь!

orgia
У меня стоит win7 64x - первый пример работает как надо. Второй пример работает 50/50 он оставляет файлы в папке Tmp Может конечно так и нужно, но первый пример ничего не оставляет в этой папке. Последний пример работает на ура! Переносит все файлы и создаёт точно такие-же папки.

Iska
16-02-2013, 17:46
Только как сделать это всё в текущем каталоге, т.е. там, где находиться сам bat-ник? »
Tco 03, у Вас опасное заблуждение о том, что текущий каталог==каталогу, в котором расположен пакетный файл. Это совершенно не так. Да, в ряде случаев они могут совпадать (например, когда Вы запускаете пакетный файл двойным щелчком из Проводника).

Текущий каталог: переменная окружения — «%CD%», ссылка с текущего каталога на самого себя — «.».

Каталог, где расположен пакетный файл: «%~dp0», где «%0» — псевдопеременная, замещающаяся именем/меткой пакетного файла, «~» — отбор возможных обрамляющих кавычек в имени, «d» и «p» — модификаторы для имени диска и пути псевдопеременной.

megaloman
16-02-2013, 18:08
Если у Вас есть каталог, в котором батник и в котором папки Tmp TmpArc TmpErr TmpIn, то вот кусок кода, который надо вставить в предыдущее решение (ограничение: в папке Tmp ни на каком уровне не должно быть подпапки c совпадающим именем Tmp) @echo off

cd /D "%~dp0"

FOR /R "Tmp\" %%f IN (*.*) DO Call :Files "%%f"
GoTo :Eof

:Files

Set TmpFtp=%1
Set TmpArc=%TmpFtp:\Tmp\=\TmpArc\%

Set TmpFtp=%~dp1
Set TmpErr=%TmpFtp:\Tmp\=\TmpErr\%
Set TmpIn=%TmpFtp:\Tmp\=\TmpIn\%

Call :CompMove %1 %TmpArc%
GoTo :Eof


далее кусок предыдущего решения Второй пример работает 50/50 он оставляет файлы в папке Tmp - заархиваруйте и перешлите Ваши батник и папки - вы меня заинтриговали. Похоже, у Вас нарушено моё предположение, следующее из условия: в архивной папке ОБЯЗЯТЕЛЬНО должен быть файл с тем же именем, что и в ТМП. Вот код, где файлы, которых нет в тмп, переместятся в ошибочные, как это сделано и в решении с поддиректориями @echo off

Set TmpFtp=D:\Tmp
Set TmpArc=D:\TmpArc
Set TmpErr=D:\TmpErr
Set TmpIn=D:\TmpIn

FOR %%f IN (%TmpFtp%\*.*) DO Call :CompMove "%%f" "%TmpArc%\%%~nxf"
GoTo :Eof

:CompMove

Set L=1
If Not Exist %2 Set L=0
If %L% EQU 1 If Not %~z1==%~z2 Set L=0
If %L% EQU 0 (
Move /Y %1 "%TmpErr%\" >nul
GoTo :Eof
)

fc /B %1 %2 >nul

If %ErrorLevel%==0 (
Move /Y %1 "%TmpIn%\" >nul
) Else (
Move /Y %1 "%TmpErr%\" >nul
)

orgia
16-02-2013, 18:41
orgia, В личном сообщении Вы писали
Цитата:
Может имеет значение что у мну стоит win7 64x? Я по пооду отработки первого варианта пакетника?
А второй пишет, что не найден пакетный файл CompMove
У меня нет в близком доступе такой системы, не берусь вникнуть в эту проблему. Обнародовал личное сообщение в надежде, что кто-то более сведущий сможет Вам помочь. »
Благодарю за старания. Буду пробовать в понедельник на работе на xp. Если и там не поедет есть надежда на дальнейшее содействие?

Tco 03
16-02-2013, 19:34
megaloman
в архивной папке ОБЯЗЯТЕЛЬНО должен быть файл с тем же именем, что и в ТМП. Вот код, где файлы, которых нет в тмп, переместятся в ошибочные »
СЕЙЧАС ВСЁ В ПОРЯДКЕ! :up: Я его просто пару раз до этого прокрутил и он оставил половину файлов в tmp, ну я его и не стал дальше крутить.
:bow: Благодарю за помощь!

orgia
19-02-2013, 11:04
Привет!
Все нормально. проверил на другом ПК, все отрабатывает на УРА. МЕГАреспект!!!!
Но возник у меня трабл. Не могу корректно прикрутить в мой батник. Идея такова. Есть входной каталог c:uarm\exg\!in. В него сваливаются сейчас файлики всех типов. 3 типа. 2 вида файликов, которые я должен контролировать с помощью батника(сравнивать с архивом на x:\archive\ГГ.ММ.ДД\out\ ), написанного megaloman. и один тип файлов, которые контролировать не надо. Файлы тянутся фтп, с разных каталогов в одну папку c:uarm\exg\!in,
Просьба помочь раскидать файлы по нужным местам. В итоге нужно: Файлы вида
set r=I%DATE:~0,2%%b%.???
set rr=L01???????????.0??
set rrr=5005805?????????????????.dat

должны контролироваться и кидаться в папку c:uarm\exg\!in
файлы вида: set o=%x%%d%???.ED - не контролироваться и просто кидаться в c:uarm\exg\!in

Вот мой батник:

@ECHO Off
if %1.==a. goto Ar & rem бR¤*¤Ё┐ Ar\
set z=
set h=c:\o\
set b=05805

set a="%DATE:~8,2%%DATE:~3,2%%DATE:~0,2%"
set x=5005805000
rem DD???.ED


set d=%DATE:~0,2%
if /i %TIME:~0,2% GTR 07 goto x
set m=%DATE:~3,2%
if %d%==01 if %m%==01 set d=31&goto x
if %d%==01 if %m%==02 set d=31&goto x
if %d%==01 if %m%==03 set d=29&goto x
if %d%==01 if %m%==04 set d=31&goto x
if %d%==01 if %m%==05 set d=30&goto x
if %d%==01 if %m%==06 set d=31&goto x
if %d%==01 if %m%==07 set d=30&goto x
if %d%==01 if %m%==08 set d=31&goto x
if %d%==01 if %m%==09 set d=31&goto x
if %d%==01 if %m%==10 set d=30&goto x
if %d%==01 if %m%==11 set d=31&goto x
if %d%==01 if %m%==12 set d=30&goto x
if /i %d% EQU 02 set d=01& goto x
if /i %d% EQU 03 set d=02& goto x
if /i %d% EQU 04 set d=03& goto x
if /i %d% EQU 05 set d=04& goto x
if /i %d% EQU 06 set d=05& goto x
if /i %d% EQU 07 set d=06& goto x
if /i %d% EQU 08 set d=07& goto x
if /i %d% EQU 09 set d=08& goto x
if /i %d% EQU 10 set d=09& goto x
set /a "d-=1"
:x
rem set q=%b%%d%???.sig

set r=I%DATE:~0,2%%b%.???
set rr=L01???????????.0??
set rrr=5005805?????????????????.dat

rem set o=o%d%%b%.???
set o=%x%%d%???.ED
rem set oo=??????????.EDS
rem set r=r???%d%%a:~3,2%.%b:~2,3%
rem set o=o%d%%b%.???
rem set o=%x%%d%???.ED


if %1.==. (runas /env /user:operator c:\uarm2\bin\uarm) else (uarm.lnk)


echo ### >>%h%log
echo ###Start: %DATE% %TIME% >>%h%log
:Loop

for /L %%i in ( 1,1,10000 ) do echo %%i>NUL
set g=

cd C:\uarm2\exg\!in\
call %h%transp.bat in mget *.*
call %h%transp.bat OUT mget *.*

rem dir /b %o%>>%h%log
if exist %o% for %%f in ( %o% ) do ( copy %%f C:\uarm2\exg\inc\ & move %%f ar\ & echo %TIME% =i/o %%f= >>%h%log )
rem if exist %oo% for %%f in ( %oo% ) do ( copy %%f C:\uarm\exg\inc\ & move %%f ar\ & echo %TIME% =i/o %%f= >>%h%log )

if exist %r% for %%f in ( %r% ) do ( copy %%f C:\uarm2\exg\cli\ & move %%f ar\ & echo %TIME% =i/o %%f= >>%h%log )
if exist %rr% for %%f in ( %rr% ) do ( copy %%f C:\uarm2\exg\cli\ & move %%f ar\ & echo %TIME% =i/o %%f= >>%h%log )
if exist %rrr% for %%f in ( %rrr% ) do ( copy %%f C:\uarm2\exg\cli\ & move %%f ar\ & echo %TIME% =i/o %%f= >>%h%log )

rem г¤*<_-Ё_ б двЁЇЁ вR<мЄR _б<Ё д*c< ЇаRи_< з_а_ ___ ___ ( в._. Ў_ RиЁЎRЄ R-)

rem ЇаЁ_┐ Ё -_
cd C:\uarm2\exg\chk\
for /L %%i in ( 1,1,200000 ) do echo %%i>NUL

rem г¤*<_-Ё_ б двЁЇЁ
if exist %o% for %%f in ( %o% ) do (call %h%transp.bat in delete %%f & echo delete %o%)
if exist %o% for %%f in ( %o% ) do (call %h%transp.bat abs put %%f & move C:\uarm2\exg\chk\%%f ar\ & set g=ok)

rem if exist %oo% for %%f in ( %oo% ) do (call %h%transp.bat in delete %%f & echo delete %o%)
rem if exist %oo% for %%f in ( %oo% ) do (call %h%transp.bat out\bnk put %%f & move C:\uarm\exg\chk\%%f ar\ & set g=ok)

rem RвЇа*ўЄ* ў -_
cd C:\uarm2\exg\ret\
if exist %r% ( for /L %%i in ( 1,1,10000 ) do echo %%i>NUL & move %r% ..\apr\ )
cd C:\uarm2\exg\out\
if exist %r% for /L %%i in ( 1,1,10000 ) do echo %%i>NUL

cd C:\uarm2\exg\ret\
if exist %rr% ( for /L %%i in ( 1,1,10000 ) do echo %%i>NUL & move %rr% ..\apr\ )
cd C:\uarm2\exg\out\
if exist %rr% for /L %%i in ( 1,1,10000 ) do echo %%i>NUL

cd C:\uarm2\exg\ret\
if exist %rrr% ( for /L %%i in ( 1,1,10000 ) do echo %%i>NUL & move %rrr% ..\apr\ )
cd C:\uarm2\exg\out\
if exist %rrr% for /L %%i in ( 1,1,10000 ) do echo %%i>NUL


rem г¤*<_-Ё_ б двЁЇЁ
if exist %r% for %%f in ( %r% ) do ( call %h%transp.bat OUT delete %%f & copy %%f C:\svk\UOS_OUT\ )
if exist %r% for %%f in ( %r% ) do ( call %h%transp.bat send put %%f & move %%f ar\ )

if exist %rr% for %%f in ( %rr% ) do ( call %h%transp.bat OUT delete %%f & copy %%f C:\svk\UOS_OUT\ )
if exist %rr% for %%f in ( %rr% ) do ( call %h%transp.bat send put %%f & move %%f ar\ )

if exist %rrr% for %%f in ( %rrr% ) do ( call %h%transp.bat OUT delete %%f & copy %%f C:\svk\UOS_OUT\ )
if exist %rrr% for %%f in ( %rrr% ) do ( call %h%transp.bat send put %%f & move %%f ar\ )


set t=%TIME:~0,2%
if %g%.==ok. if /i %t% LEQ 6 set z=yes
rem ў_бм ¤_-м ЇаRбвR жЁЄ<Ё┐, * ЇRб<_ 0 з*бRў...
if /i %t% GEQ 6 goto Loop

rem _б<Ё -Rзм ЇRб<_ 3 Ё z=yes в._. д*c<л ЇаЁ-Ё┐*<Ёбм ¤R 6 гва*- *ў_аи*_┐
if /i 3 LEQ %t% if %z%.==yes. goto stop
goto Loop

:stop
echo ### EXIT:%TIME% >>%h%log
:Ar
cd C:\uarm2\exg\!in\ & ren ar 20%a% & md ar
cd C:\uarm2\exg\chk\ & ren ar 20%a% & md ar
cd C:\uarm2\exg\out\ & ren ar 20%a% & md ar
cd C:\uarm2\stg\err\ & ren ar 20%a% & md ar

for /L %%i in ( 1,1,200000 ) do echo %%i>NUL
shutdown /f /s




© OSzone.net 2001-2012