Comparison of the lines with batch

2020-07-24 07:05发布

问题:

I want to compare the first column of before.txt with the first column of after.txt line per line ( the first with the first,the second with the second and so on). As output now I get only the last value E992A84B8C8A1FEF3B94242403D5D84B two times. My question is how to compare all the lines and get the result message?

 FOR /F "tokens=1 delims= " %%G IN (before.txt) DO set variable1=%%G
    FOR /F "tokens=1 delims= " %%I IN (after.txt) DO set variable2=%%I 
    echo !variable1!
    echo !variable2!

 if /I !variable1!==!variable2! (
     echo !variable1! !variable2! md5sum check is ok
     )

after.txt

94F948D2615318505FD84D722A6F5F4F  U:\testbmbf\0012\F96B1522A\MASTER\00000001.tif
4F5022E3290A9A8A4E8905C5CAAFB1A6  U:\testbmbf\0012\F96B1522A\MASTER\00000002.tif
776DF4069AD1914D9C37593E423BC0E4  U:\testbmbf\0012\F96B1522A\MASTER\00000003.tif
95EC963E9C789B3502E1E2C85E505218  U:\testbmbf\0012\F96B1522A\MASTER\00000004.tif
D5DD98F880A7204092EAA9355A4B558B  U:\testbmbf\0012\F96B1522A\MASTER\00000005.tif
1A08F9B01904F3EF689B44093343AE2C  U:\testbmbf\0012\F96B1522A\MASTER\00000006.tif
437DC62245852A01CCF4F2689F82920E  U:\testbmbf\0012\F96B1522A\MASTER\00000007.tif
A4E7C76EC523F1E2799BE8CE049D28FC  U:\testbmbf\0012\F96B1522A\MASTER\00000008.tif
177689553B9D9392AD6B72130EE1D22F  U:\testbmbf\0012\F96B1522A\MASTER\00000009.tif
EB0F2F741428CF376909AB65BEF6659F  U:\testbmbf\0012\F96B1522A\MASTER\00000010.tif
E992A84B8C8A1FEF3B94242403D5D84B  U:\testbmbf\0012\F96B1522A\MASTER\00000011.tif

before.txt

94F948D2615318505FD84D722A6F5F4F  U:\testbmbf\0012\F96B1522A\00000001.tif
4F5022E3290A9A8A4E8905C5CAAFB1A6  U:\testbmbf\0012\F96B1522A\00000002.tif
776DF4069AD1914D9C37593E423BC0E4  U:\testbmbf\0012\F96B1522A\00000003.tif
95EC963E9C789B3502E1E2C85E505218  U:\testbmbf\0012\F96B1522A\00000004.tif
D5DD98F880A7204092EAA9355A4B558B  U:\testbmbf\0012\F96B1522A\00000005.tif
1A08F9B01904F3EF689B44093343AE2C  U:\testbmbf\0012\F96B1522A\00000006.tif
437DC62245852A01CCF4F2689F82920E  U:\testbmbf\0012\F96B1522A\00000007.tif
A4E7C76EC523F1E2799BE8CE049D28FC  U:\testbmbf\0012\F96B1522A\00000008.tif
177689553B9D9392AD6B72130EE1D22F  U:\testbmbf\0012\F96B1522A\00000009.tif
EB0F2F741428CF376909AB65BEF6659F  U:\testbmbf\0012\F96B1522A\00000010.tif
E992A84B8C8A1FEF3B94242403D5D84B  U:\testbmbf\0012\F96B1522A\00000011.tif

回答1:

The usual way to read several files in parallel is described at this answer and consists of read the first file via a for /F command and the other file(s) via redirected set /P command(s). For example:

@echo off
setlocal EnableDelayedExpansion

rem First file is read with FOR /F command
rem Second file is read via redirected stdin
< after.txt (for /F %%G in (before.txt) do (
   rem Read next line from after.txt
   set /P "variable2="
   rem Compare first token of both files
   for /F %%I in ("!variable2!") do (
      if /I %%G==%%I (
         echo %%G %%I md5sum check is ok
      )
   )
))

Note that the default for /F behavior is get the first token delimited by space, so "tokens=1 delims= " option is not necessary...

However, if the files are small you may use a simpler method:

@echo off

for /F "tokens=1,2 delims=: " %%F in ('findstr /N "^" before.txt') do (
   for /F "tokens=1,2 delims=: " %%H in ('findstr /N "^" after.txt') do (
      if %%F equ %%H if /I %%G == %%I (
         echo %%G  %%I md5sum check is ok
      )
   )
)

In this method a findstr /N "^" command is used to enumerate all lines in both files, so if %%F equ %%H command is used to synchronize (select the same) lines in both files. This method is not efficient, so it will take longer if the files are not small...



回答2:

Aschipl's batch tweaked to your requirements:

:: Q:\Test\2018\04\27\SO_50067394.cmd
@echo off
setlocal EnableExtensions EnableDelayedExpansion

set "FILE1=after.txt"
set "FILE2=before.txt"
:: set "RET=Comparison.txt" & rem // (none to output to console)
if not defined RET set "RET=con"

for /F %%C in ('^< "%FILE1%" find /C /V ""') do set "NUM1=%%C"

4< "%FILE1%" 3< "%FILE2%" > "%RET%" (
     for /L %%I in (1,1,%NUM1%) do (
         set "LINE1="
         0<&4 set /P "LINE1="
         set "LINE2="
         0<&3 set /P "LINE2="
         if not ErrorLevel 1 If "!LINE1:~0,32!"=="!LINE2:~0,32!" echo(!LINE1:~0,32! !LINE2:~0,32! md5sum check is ok
     )
)

endlocal
exit /B

Sample output:

> Q:\Test\2018\04\27\SO_50067394.cmd
94F948D2615318505FD84D722A6F5F4F 94F948D2615318505FD84D722A6F5F4F md5sum check is ok
4F5022E3290A9A8A4E8905C5CAAFB1A6 4F5022E3290A9A8A4E8905C5CAAFB1A6 md5sum check is ok
776DF4069AD1914D9C37593E423BC0E4 776DF4069AD1914D9C37593E423BC0E4 md5sum check is ok
95EC963E9C789B3502E1E2C85E505218 95EC963E9C789B3502E1E2C85E505218 md5sum check is ok
D5DD98F880A7204092EAA9355A4B558B D5DD98F880A7204092EAA9355A4B558B md5sum check is ok
1A08F9B01904F3EF689B44093343AE2C 1A08F9B01904F3EF689B44093343AE2C md5sum check is ok
437DC62245852A01CCF4F2689F82920E 437DC62245852A01CCF4F2689F82920E md5sum check is ok
A4E7C76EC523F1E2799BE8CE049D28FC A4E7C76EC523F1E2799BE8CE049D28FC md5sum check is ok
177689553B9D9392AD6B72130EE1D22F 177689553B9D9392AD6B72130EE1D22F md5sum check is ok
EB0F2F741428CF376909AB65BEF6659F EB0F2F741428CF376909AB65BEF6659F md5sum check is ok
E992A84B8C8A1FEF3B94242403D5D84B E992A84B8C8A1FEF3B94242403D5D84B md5sum check is ok


回答3:

An off topic powershell answer with the same result

## Q:\Test\2018\04\27\SO_50067394.ps1
$after  = Import-csv .\after.txt  -delimiter ' ' -header MD5,X,FileName
$before = Import-csv .\before.txt -delimiter ' ' -header MD5,X,FileName

for ($I=0;$I -le $after.Count;$I++) {
  If ($after[$i].MD5 -eq $before[$I].MD5){
    "{0} {1} md5sum check is ok" -f $after[$i].MD5,$before[$I].MD5
  } else {
    "MD5 differs between files {0} and {1}" -f $after[$i].FileName,$before[$I].FileName5
  }
}


回答4:

You can set 2 counters. When the counters are equal you test the 2 columns. This way you get also the line number of the error !

@echo off

setlocal enabledelayedexpansion

set $counter1=1

for /f "delims= " %%a in (before.txt) do (
   set $counter2=1
   for /f "delims= " %%b in (after.txt) do (
        if !$counter1!==!$counter2! (
            if "%%a"=="%%b" (echo line !$counter1! cheksum OK
            ) else (echo line !$counter1! cheksum KO)
        )
        set /a $counter2+=1
   )
   set /a $counter1+=1
   )

Output :

line 1 cheksum OK
line 2 cheksum OK
line 3 cheksum OK
line 4 cheksum OK
line 5 cheksum OK
line 6 cheksum OK
line 7 cheksum OK
line 8 cheksum OK
line 9 cheksum KO
line 10 cheksum OK
line 11 cheksum OK