1

I have to run an executable (written in C#) 42 times separately for 42 US states on Windows command line. I wrote a batch file to automate the process. The 1st user input to the executable is 1, and the 2nd one is the state abbreviation (AL, AZ, CT etc.). I have written the following script to do it:

@echo off

for /f "tokens=1 delims=" %%x in (CropHailStates.txt) do (

    (echo 1 & echo %%x)|Z:\Models\LossCalc.exe 
)

Each row in CropHailStates.txt file contains the state abbreviation as follows:

AL

AZ

CT

Now in manual mode, when 1 is entered at the 1st prompt and AL is entered at the 2nd, the C# program reads a file named "AL.Even.CropLoss.csv". But when I run the batch script to do it automatically, I get the error message saying that the file "AL .Even.CropLoss.csv" is not found. The problem is related to the extra whitespace after AL. It’s somehow adding the whitespace after inserting the state abbreviation. It’s like pressing the spacebar after writing the state abbreviation, but before pressing enter.

How can I get rid of that extra whitespace in the file name?

dbenham
  • 127,446
  • 28
  • 251
  • 390
Kazi Ahmed
  • 11
  • 2

3 Answers3

3

The problem is an artifact of the pipe parser when dealing with a parenthesized block of code.

The source of the problem is described by jeb at Why does delayed expansion fail when inside a piped block of code?. Each side of the pipe is executed in a new CMD /C process.

When a multi-line parenthesized block gets piped, the parser must repackage the entire block into a single line so that it can be executed via CMD /C

(
  echo line 1
  echo line 2
) | findstr "^"

The left side of the pipe is executed as:

C:\WINDOWS\system32\cmd.exe  /S /D /c" ( echo line 1 & echo line 2 )"

You can see the extra spaces that are introduced.

Even though your code is already on a single line, it still goes through the same parser that introduces those pesky spaces.

I know of three relatively simple solutions that eliminate the unwanted spaces without the need for a temporary file.

1) Add an extra CMD /C where you explicitly get the exact behavior you are looking for

@echo off
for /f "tokens=1 delims=" %%x in (CropHailStates.txt) do (
  cmd /c "echo 1&echo %%x"|Z:\Models\LossCalc.exe 
)

2) Store part of the command in a variable and delay expansion until execution of CMD /C

@echo off
setlocal
for /f "tokens=1 delims=" %%x in (CropHailStates.txt) do (
  set "cmd=&echo %%x"
  (echo 1%%cmd%%)|Z:\Models\LossCalc.exe 
)

3) Introduce delayed expansion of a linefeed variable - a mind blowing technique developed by jeb that he describes in that same SO link that I provided

@echo off
setlocal
set ^"LF=^
%= This creates a linefeed character =%
"
for /f "tokens=1 delims=" %%x in (CropHailStates.txt) do (
  (echo 1%%LF%%echo %%x%%LF%%)|Z:\Models\LossCalc.exe
)
dbenham
  • 127,446
  • 28
  • 251
  • 390
2
   (echo 1& echo %%x)>tempfile.txt
   Z:\Models\LossCalc.exe <tempfile.txt
   del tempfile.txt

should provide the data without the trailing spaces

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • This totally works! But 3 other solutions provided by @dbenham do have the advantage of not having to create the tempfile. – Kazi Ahmed Dec 08 '17 at 16:05
-1

To get rid of the last character (the whitespace) you can do:

@echo off
setlocal EnableDelayedExpansion

for /f "tokens=1 delims=" %%x in (CropHailStates.txt) do (
    set "result=%%x"
    (echo 1 & echo !result:~0,-1!)|Z:\Models\LossCalc.exe 
)

Hope it helps.

dcg
  • 4,187
  • 1
  • 18
  • 32
  • The space is not coming from the data. It seems to be a side affect of using parentheses. Test this and you will see what I mean. `(echo 1&echo AZ)|findstr "1 AZ">>test.txt`. – Squashman Dec 07 '17 at 21:50
  • @Squashman: Hmm. Your code yielded a terminal space on each line for me (filesize 9 bytes) but when the pipe was removed, the output had no spaces. The space before the `echo` after the `&` had no effect... – Magoo Dec 08 '17 at 02:14
  • This totally fails because [delayed expansion does not work when a parenthesized block is piped](https://stackoverflow.com/q/8192318/1012053). Plus it does not address the underlying issue. – dbenham Dec 08 '17 at 17:21
  • Thanks for the comments. I focused on removing the last character instead of the actual problem. I'll keep it in mind. – dcg Dec 11 '17 at 20:03