3

I'm trying to read a list of values/strings (they vary between letters and numbers) from a text file, if the value/string exist in the an output text file do nothing, else append it to the text file.

I spent over 3 days doing research and trying all sort of things and ideas. On my search I came across a post very similar (link below) to what i need to do but since i'm new to Programming and literally I have no one to ask for help, I'm hoping you guys can help me out.

Comparing Strings in Batch inside a for (if statement))

So used something very similar to the post above, but I don't know I'm just tired or I'm just blind to see where I'm doing things wrong.

@echo off
set ProjectNo=12345
set ProjectLocation=X:\Projects\123 ABC\45 WALL\G Drafting 12345\02 Models
set location=X:\Scripts
set areas=%location%\%ProjectNo%-AREAS.txt
set MAT=%location%\%ProjectNo%-MAT.txt

setlocal enableextensions enabledelayedexpansion


for /F %%a in ("%areas%") do (
    set "MA=%%a"
    setlocal EnableDelayedExpansion
    echo(!MA!
    pause
    if exist "!MA!"=="!MA:%MA%=!" (
        echo matched
        > nul
        ) else ( 
        echo nomatch
        > %MAT%
        )
        endlocal
    )
)

endlocal
pause 

Content of 12345-AREAS.txt is as follow (current):

01 
01 
10 
10 
10 
10 
130 
15 
15 
15
20 
20 
20 
20
25 
25 
25
30 
30 
30 
30 

This list could vary from 10 - 300 values (varies a lot)

What i aim to obtain in the output file 12345-MAT.txt is single and unique value of each like so:

01
10
130
15
20
25
30
Enzo
  • 39
  • 7

2 Answers2

3

So you are after a sort unique.

Here a variant which doesn't need delayed expansion,
by setting env vars with the items enclosed in _[]

@echo off
set "ProjectNo=12345"
set "ProjectLocation=X:\Projects\123 ABC\45 WALL\G Drafting 12345\02 Models"
set "location=X:\Scripts"
set "areas=%location%\%ProjectNo%-AREAS.txt"
set "MAT=%location%\%ProjectNo%-MAT.txt"

Setlocal
:: clear env vars _[
for /f "delims=" %%A in ('set _[ 2^>Nul') Do set "%%A="

(for /f %%A in ('sort ^<"%areas%"')  Do if not defined _[%%A] (
    set "_[%%A]=1"
    Echo:%%A
  )
) > "%MAT%"
  • am I understanding correctly that the first loop basically you are making %%A a variable for the second loop? – Enzo Mar 28 '19 at 21:18
  • 3
    No, to assure no vars also begining with `_[` are present before processing. The trick is that although I'm setting a variable inside a (code block) the `if defined` will check the actual state and not the state when first entering the block at parse time. –  Mar 28 '19 at 21:21
  • Thank you for making me less ignorant today! – Enzo Mar 28 '19 at 21:29
  • @aschipfl the `if defined` asures no doublettes are output. –  Apr 25 '19 at 22:36
3

Here is a simple approach that sorts the text data, reads the text line by line, compares each line with the previous one and returns the current one only in case of mismatch:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Reset buffer for previous line:
set "PREV="
rem // Write to output file:
> "12345-MAT.txt" (
    rem // Read lines from input file:
    for /F delims^=^ eol^= %%L in ('sort "12345-AREAS.txt"') do (
        rem // Store current line:
        set "LINE=%%L"
        rem // Toggle delayed expansion to not lose `!`-signs:
        setlocal EnableDelayedExpansion
        rem // Compare current line with previous one:
        if not "!LINE!"=="!PREV!" echo(!LINE!
        endlocal
        rem // Store line for next loop iteration:
        set "PREV=%%L"
    )
)

endlocal
exit /B

The advantage of this method is that all characters may occur; the disadvantage might be the modest performance.

aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Thanks for the alternative! love it! Could you please explain me how `for /F delims ^=^ eol^= ` works, to my understanding you always have to quote mark delims. – Enzo Mar 29 '19 at 15:11
  • You're welcome! Yes, usually the `for /F` options should be quoted; however, to disable both `delims` (defaults to _space_ and _tab_) and `eol` (defaults to `;`) this special syntax is needed (`^` is the escape character in `cmd` needed here to not interpret _space_ and `=` as token separator); see also [this thread](https://stackoverflow.com/q/32192678) for this topic... – aschipfl Mar 29 '19 at 15:45