Search code examples
batch-filesass

Trouble comparing strings


As practice for learning Windows Batch programming, I'm trying to create a batch file which will process all the SCSS files in a folder and compile them into CSS. I am running into an issue while trying to filter out all files that begin with an underscore as these files are snippets only to be used in @import statements.

The batch file I have so far is:

@echo off
SETLOCAL EnableDelayedExpansion
FOR /R "D:\Jaye\Programming\Web\Project\scss" %%G IN (*.scss) DO (
    SET name=%%~nG
    echo !name!
    SET firstChar=!name:~0,1!
    echo !firstChar!
    if !firstChar! == "_" (
        echo "Dont process this file"
    )
)
ENDLOCAL

The ...\Project\scss folder contains the following four files:

main.scss
menus.scss
content.scss
_uiColors.scss

The output I'm getting is:

content
c
main
m
menus
m
_uiColors
_

The important issue here is that the _uiColors.scss file is not triggering the if statement on line 9 of the bat file. Based on the output I can see that it is setting the firstChar variable to an underscore as expected but when that gets compared in the if statement something isn't evaluating as I expect. I'd like to know why "_"=="_" is seeming evaluating to false (is it a type mismatch maybe?) and then what I might try to fix it.

Thanks

EDIT (with answer): I've got it working now thanks to the answers by Mofi and Gerhard. Thanks guys. The issue I ran into is due to my assumptions based on previous experience with other more modern languages I was using quotation marks incorrectly when working with strings.


Solution

  • By double quoting only one side of statement, you are not comparing the same thing:

    Examples:

    if apples == "apples"
    

    put them underneath each other:

    apples
    "apples"
    

    These two cannot match, ever. You can almost consider it that the one side of the statement has 2 additional characters.

    So by quoting both values either side of the == you will get a proper match, you just need:

    if "!firstChar!" == "_"
    

    Additionally, you did not need to create the firstchar variable, you could have just used the following, though it would really only save you one line of code:

    if "!name:~0,1!" == "_"
    

    So far you also do not have an else statement, so the if parenthesis block is not needed either. So your code could be:

    @echo off & setlocal EnableDelayedExpansion
    FOR /R "D:\Jaye\Programming\Web\Project\scss" %%G IN (*.scss) DO (
        SET name=%%~nG
        echo !name!
        echo !name:~0,1!
        if "!name:~0,1!" == "_" echo "Dont process this file: %%~nG"
    )
    

    Lastly, you could do this exact same thing, by simply excluding the files starting with _ by including findstr and therefore do not require the if statements, nor require delayedexpansion:

    @echo off
    pushd "D:\Jaye\Programming\Web\Project\scss"
    for /f "delims=" %%i in ('dir /b /s /a-d *.scss ^| findstr /V /IRC:"^_"') do echo Non of these starts with "_": "%%~i"
    popd