Multiply a Value in a Text file

August 4, 2009 at 06:51:45
Specs: Windows
Hi Everyone,

I have a text file that contains values such as the following:

82000491675,10511,0,1.9,,7
82184045954,10206,44.99,2.2,,7
80686002123,10210,49.99,2.7,,7
5099873013724,10223,34.99,2.75,,7

My problem is that I need a batch file to multiply the value in the 3rd last field (in bold) by a factor of 100 and return the results in a new text file.

Is this even possible? Thank you in advance.


See More: Multiply a Value in a Text file

Report •


#1
August 4, 2009 at 14:48:45
Hi Mick

Batch only does integer maths, but if there's no more than 2 decimal places and the number is always the 4th varable.
Try this.

@echo off
SetLocal EnableDelayedExpansion

type nul > Data2.txt
for /f "tokens=4 delims=," %%a in (Data.txt) do (
for /f "tokens=1-2 delims=." %%b in ("%%a") do (
set /a Num=%%b%%c*10
echo !Num:~,3! >> Data2.txt
)
)


Report •

#2
August 4, 2009 at 17:35:42
Hi dtech10,

Cheers for a quick response. Much appreciated.

There is no more than 2 decimal places and the number is always the 4th varable.

I tried the script you have above and for the most part it worked fine. There are some values that return an error (Invalid number. Numeric constants are either decimal (17), hexadecimal (0x11), or octal (021)), and don't calculate correctly.
An original value of 240 returns a result of 240; 0.8 returns 130; and, 1.3 returns 130.

I would also like to have all the other fields from the original file in the new one, but I'm more concerned about the calculation at this point.

Regards...


Report •

#3
August 4, 2009 at 20:57:28
You gotta wonder which wunderkind thought 0n should be octal.

===================================
@echo off > Data2.txt & SetLocal EnableDelayedExpansion

for /f "tokens=4 delims=," %%a in (Data.txt) do (
for /f "tokens=1-2 delims=." %%b in ("%%a") do (
if %%b neq 0 (
set /a Num=%%b%%c*10
) else (
set /a Num=%%c*10
)
echo !Num:~,3! >> Data2.txt
)
)


=====================================
If at first you don't succeed, you're about average.

M2


Report •

Related Solutions

#4
August 4, 2009 at 22:11:32
Thanks for that Mechanix2Go. Unfortunately, i got the same result as with the previous from dtech10, but I think I have found a pattern to the errors if it helps you guys to work out what is going on. It seems that the data I provided in the initial post failed to show that the variable can also be an integer with no decimal place value. Probably best explained below:

"1.11" returns "111" which is correct
"1.1" returns "110" which is correct
"1.0" returns "100" which is correct
"1.00" returns "10" which is incorrect
"1" returns "10" which is incorrect

The part that confuses me the most is that 1.0 returns a correct value, but 1.00 will not.

I hope this is clearer mate. Thanks again.


Report •

#5
August 5, 2009 at 07:14:53
Also if you have more than one digit before the decimal point, you will also get the wrong answer.

Which shows that hacking with a language that's not suited to the job is unproductive.


Report •

#6
August 5, 2009 at 07:46:46
I'm with klint on this one. If you must use a native language, VBScript is the best option here.

Report •

#7
August 5, 2009 at 07:50:56
Despite what I said about batch being the wrong language, here is my solution. Note that it doesn't use SET /A and therefore is not prone to misinterpretation in the presence of leading zeros, therefore the line CALL :strip_leading_zeros is optional, it does not give wrong results if you omit it but you may want to keep it for presentational reasons.

Only known caveats: it doesn't handle numbers of the form ".1234", you need at least one digit before the decimal point, i.e. "0.1234". Also it has not been tested on negative numbers.

@echo off
setlocal EnableDelayedExpansion

(for /f "tokens=4 delims=," %%a in (Data.txt) do (
   for /f "tokens=1-2 delims=." %%b in ("%%a") do (
      set decimalpart=%%c00
      set num=%%b!decimalpart:~,2!
      call :strip_leading_zeros
      echo !num!
   )
)) > Data2.txt

:strip_leading_zeros
if not "%num:~,1%"=="0" goto :eof
set num=%num:~1%
goto :strip_leading_zeros


Report •

#8
August 5, 2009 at 15:58:43
If you can use non native options, here's my Perl solution.

C:\test>type data.txt
82000491675,10511,0,1.9,,7
82184045954,10206,44.99,2.2,,7
80686002123,10210,49.99,2.7,,7
5099873013724,10223,34.99,2.75,,7
C:\test>
C:\test>perl -F',' -ane "BEGIN{$,=','} $F[3]=int($F[3]*100); print @F," data.txt

82000491675,10511,0,190,,7
82184045954,10206,44.99,220,,7
80686002123,10210,49.99,270,,7
5099873013724,10223,34.99,275,,7


Report •

#9
August 5, 2009 at 16:39:23
Awesome klint... that worked 100% on 21000 lines. Thanks a lot for that.

I get what you guys are saying about using a batch file to do something it was never meant to do.

Now is there anyway to have it recreate the original file with those new calculated values back in the spot they where in?

Also, on rare occasions that field contains a 0 (zero) value. Can we make it so those are skipped altogether? I don't mind if they have to be removed first. It's just that a zero value halts the process for the rest of the file.

Any assistance that you guys can offer is very much appreciated.

Michael.


Report •

#10
August 7, 2009 at 14:33:37
Hi
I've modified Klint code to help with the zero problem.
I'll work on the other problem.
Do you need the numbers written to another file, as they maybe could be modified as the file is being processed the first time.
If you do need the file it could be processed and written but it would be fast with 21000 lines.
Hope the code below helps anyway.


@echo off
setlocal EnableDelayedExpansion

(for /f "tokens=4 delims=," %%a in (Data3.txt) do (
for /f "tokens=1-2 delims=." %%b in ("%%a") do (
set decimalpart=%%c00
set num=%%b!decimalpart:~,2!
call :strip_leading_zeros
if "!num!" EQU "" (set num=0)
echo [%%a] [!num!]
)
))
exit /b

:strip_leading_zeros
if not "%num:~,1%"=="0" exit /b
set num=%num:~1%
goto :strip_leading_zeros


Report •

#11
August 8, 2009 at 23:10:33
Nice one dtech10... That solved the zero problem alright.

The 21000 line file was just a test I was doing to ensure accuracy. In reality I don't expect to have to process more than 2000 lines at a time.

I would like them to be in the same file, but I think that this problem might be solved on my other post. I thought I might not be able to ask too many questions in the one thread, so I started another to split them up.

Again... thanks to all you guys for your help and patience.

Regards,

Michael.


Report •


Ask Question