1

I wrote batch script to copy CSS files over to a certain directory and the problem is exclamation marks are removed when I open the CSS files in the destination directory.

The original CSS contains styles with exclamation marks such as:

.foo
{
   color: pink !important;
}

My CSS outcome becomes

.foo
{
   color: pink important;
}

I looked into the root cause of this and based on: exclamation point being removed constantly in batch file

But I cannot figure out where I need to disable delayed expansion in my case.

FYI, my batch is doing followings:

  1. for each theme string separated by comma, find start and end of line numbers that matches certain string.

  2. now I have start and end line numbers (example 500 and 1000)

  3. copy the file contents except between line 500 and 1000

  4. the finalized file is copied over to destination directory

Please let me know if you need more clarification, thanks in advance.

Batch (snippet):

set themes=Platinum,Granite,Sun,Sky,Burgundy,Leaf,Twilight,Sharepoint 2010,Sharepoint 2013

rem Directory that contains theme css files
set RUNTIME_DEST=%K2DIR%\K2 SmartForms Runtime\Styles\Themes

REM Do something with each substring

call :parse "%themes%"
goto :eof

:parse
setlocal

for %%a in ("%themes:,=" "%") do (
   call :getLineNumber %%a
)
endlocal
goto :eof

:getLineNumber
setlocal
echo file name is %~1
set filename=%~1
rem Get start and end line numbers of the unwanted section
for /F "delims=:" %%a in ('findstr /N /C:"PickerCollectionThemeStart" "%RUNTIME_DEST%\%filename%.css"') do (
    set start=%%a
)

for /F "delims=:" %%a in ('findstr /N /C:"PickerCollectionThemeEnd" "%RUNTIME_DEST%\%filename%.css"') do (
   set end=%%a
)

if not defined start (
    echo start not defined...
    set start=0
    set end=0
)

echo start val = !start!
echo end val = !end!


call :resetTheme "%filename%" "%start%" "%end%"
endlocal
goto :eof

:resetTheme
setlocal
set filename=%~1
set start=%~2
set end=%~3


echo %fileName%
echo %start%
echo %end%
echo ---------------

rem Create a copy file to modify
xcopy "%RUNTIME_DEST%\%filename%.css" "%cd%\Batch_tmp" /y /z /r

echo creating tmp copy...
rem Rename the file so we can modify and create finalized version
ren "Batch_tmp\%fileName%.css" "%fileName%_tmp.css"

echo coping all line except section...

rem Copy all lines, except the ones in start-end section
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "Batch_tmp\%fileName%_tmp.css"') do (
    if %%a lss %start% echo(%%b
    if %%a gtr %end% echo(%%b
 )) > Batch_tmp\!fileName!.css

echo copying to blackpearl dir
rem Finally move the css over to blackpearl directory

setlocal DisableDelayedExpansion
xcopy "Batch_tmp\%fileName%.css" "%RUNTIME_DEST%"  /y /z /r
endlocal

endlocal
goto :eof

:eof

pause

UPDATE

Below is my solution that works based on the advice. The difference is, as instructed, set EnableDelayedExpansion at the beginning of script to make the effect on entire batch scope then set DisableDelayedExpansion only where it applies.

set themes=Platinum,Granite,Sun,Sky,Burgundy,Leaf,Twilight,Sharepoint 2010,Sharepoint 2013

rem Directory that contains theme css files
set RUNTIME_DEST=%K2DIR%\K2 SmartForms Runtime\Styles\Themes

REM Do something with each substring

call :parse "%themes%"
goto :eof

:parse
setlocal
for %%a in ("%themes:,=" "%") do (
    echo ------------------------
    call :getLineNumber %%a
)
endlocal
goto :eof

:getLineNumber
setlocal
echo file name is %~1
set filename=%~1
rem Get start and end line numbers of the unwanted section
for /F "delims=:" %%a in ('findstr /N /C:"PickerCollectionThemeStart" "%RUNTIME_DEST%\%filename%.css"') do (
    set start=%%a
)

for /F "delims=:" %%a in ('findstr /N /C:"PickerCollectionThemeEnd" "%RUNTIME_DEST%\%filename%.css"') do (
   set end=%%a
)

if not defined start (
    echo start not defined...
    set start=0
    set end=0
)

echo start val = !start!
echo end val = !end!


call :resetTheme "%filename%" "%start%" "%end%"
endlocal
goto :eof

:resetTheme
setlocal
set filename=%~1
set start=%~2
set end=%~3

echo %fileName%
echo %start%
echo %end%

rem Create a copy file to modify
xcopy "%RUNTIME_DEST%\%filename%.css" "%cd%\Batch_tmp" /y /z /r

echo creating tmp copy...
rem Rename the file so we can modify and create finalized version
ren "Batch_tmp\%fileName%.css" "%fileName%_tmp.css"

echo coping all line except section...

rem Copy all lines, except the ones in start-end section
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "Batch_tmp\%fileName%_tmp.css"') do (
    setlocal DisableDelayedExpansion
    if %%a lss %start% echo(%%b
    if %%a gtr %end% echo(%%b
    endlocal
 )) > Batch_tmp\!fileName!.css

echo copying to blackpearl dir
rem Finally move the css over to blackpearl directory

xcopy "Batch_tmp\%fileName%.css" "%RUNTIME_DEST%"  /y /z /r

endlocal
goto :eof

:eof
Community
  • 1
  • 1
Meow
  • 18,371
  • 52
  • 136
  • 180
  • disable the delayed expansion, in your snippet it's not necessary. – Endoro Jun 28 '13 at 17:50
  • It is necessary because I have !filename!.css which could not be converted otherwise. – Meow Jun 28 '13 at 18:23
  • 1
    Can't see that. `filename` is not changed within `resettheme` once it's established at the start, so `%filename%` and `!filename!` should be the same... – Magoo Jun 28 '13 at 18:39
  • hmm but when I set DisableDelayedExpansion, outcome file names are !filename!.css instad of being replaced by something like "foobar.css" – Meow Jun 28 '13 at 18:57
  • 1
    replace `!filename!` in `)) > Batch_tmp\!fileName!.css` with `%filename%` and disable delayed expansion in the script. – Endoro Jun 28 '13 at 19:14
  • downvoters, please specify why downvote. without reason, its pointless. – Meow Jul 12 '13 at 17:49

1 Answers1

4

I'd put it here were I you...

(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "Batch_tmp\%fileName%_tmp.css"') do (
    SETLOCAL DISABLEDELAYEDEXPANSION
    if %%a lss %start% echo(%%b
    if %%a gtr %end% echo(%%b
    ENDLOCAL
 )) > Batch_tmp\!fileName!.css

but no guarantees...


Disappointing results reported by OP :(

Here's my test setup:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:: force directories, start and end
SET runtime_dest=c:\temp
SET filename=test
SET start=2
SET end=4

:: create batch_temp & clear

MD "%cd%\Batch_tmp" 2>NUL >NUL
DEL "%cd%\Batch_tmp\*?*" /F /Q

:: make copy of original .css
xcopy "%RUNTIME_DEST%\%filename%.css" "%cd%\Batch_tmp" /y /z /r

echo creating tmp copy...
rem Rename the file so we can modify and create finalized version
ren "Batch_tmp\%fileName%.css" "%fileName%_tmp.css"

echo coping all line except section...
rem Copy all lines, except the ones in start-end section
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "Batch_tmp\%fileName%_tmp.css"') do (
    if %%a lss %start% echo(%%b
    if %%a gtr %end% echo(%%b
 )) > Batch_tmp\!fileName!.css
rem Copy all lines, except the ones in start-end section
(for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "Batch_tmp\%fileName%_tmp.css"') do (
SETLOCAL disabledelayedexpansion
    if %%a lss %start% echo(%%b
    if %%a gtr %end% echo(%%b
ENDLOCAL
 )) > Batch_tmp\!fileName!WITHSETLOCAL_ENDLOCAL.css

ECHO ============================
ECHO Batch_tmp\%fileName%_tmp.css
TYPE Batch_tmp\%fileName%_tmp.css
ECHO =======^^^^^^^^=================this is the original file
ECHO Batch_tmp\%fileName%.css
TYPE Batch_tmp\%fileName%.css
ECHO =======^^^^^^^^=================this is the result with delayed expansion enabled
ECHO Batch_tmp\%fileName%WITHSETLOCAL_ENDLOCAL.css
TYPE Batch_tmp\%fileName%WITHSETLOCAL_ENDLOCAL.css
ECHO ========^^^^^^^^================this is the result with the advised setlocal/ENDLOCAL IN place
GOTO :eof

And results:

C:\temp\test.css
1 File(s) copied
creating tmp copy...
coping all line except section...
============================
Batch_tmp\test_tmp.css
.foo
omit me
and me
and me
{
   color: pink !important;
}
=======^^^^=================this is the original file
Batch_tmp\test.css
.foo
{
   color: pink important;
}
=======^^^^=================this is the result with delayed expansion enabled
Batch_tmp\testWITHSETLOCAL_ENDLOCAL.css
.foo
{
   color: pink !important;
}
========^^^^================this is the result with the advised setlocal/ENDLOCAL IN place

So - all I can say is "Works for me!"

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • thanks for the update, you are right. I think I had some other thing (other part of the code) was preventing from getting the right value. Your solution worked after I clear that issue. – Meow Jun 29 '13 at 18:01