How to remove leading zeros from comma delimited file

I have a file ( file1.csv

) which has two values ​​separated by commas. I need a way to remove leading zero from both values ​​in one batch file.

So far I have used this:

@echo off
(for /f "tokens=*,* delims=0" %%a in (file1.csv) do echo(%%a)>stripped.txt

      

It works pretty well, although it only removes the zero from the first number, not the second.

Example from file1.csv

:

00012345,00000012345 

00067890,00000067890

      

Example from stripped.txt

after using the above batch file:

12345,00000012345

67890,00000067890

      

Does anyone have any suggestions on how I can do the same for the decimal place?

+3


source to share


2 answers


If you want to use a hybrid JScript / batch utility called REPL.BAT then the solution can be as simple as:

type file.csv|repl "0*(\d\d*),0*(\d\d*)" "$1,$2" >stripped.csv

      

This is not just a REPL.BAT solution, but also very effective. It can handle large CSVs pretty quickly.

If you must have a clean batch solution, then here is one that does not use CALL or GOTO or slow expansion and it handles the value 0 correctly. This will be significantly slower than the REPL.BAT solution, but I think this is the most efficient solution for clean batch solution.

The first loop parses the string into two values.

Then there are two more loops for each value. The first line contains leading zeros, but also adds an extra value of 0 after the space, so that it always returns a string, even if the value is 0. The last loop then returns either the original null value, or if it was excluded because it is 0, then it returns the appended value 0.



@echo off
(for /f "delims=, tokens=1,2" %%A in (file.csv) do (
  for /f "delims=0 tokens=*" %%C in ("%%A 0") do for /f %%E in ("%%C") do (
    for /f "delims=0 tokens=*" %%D in ("%%B 0") do for /f %%F in ("%%D") do (
      echo %%E,%%F
    )
  )
))>stripped.csv

      

The code to remove leading zeros can be encapsulated into a function and then more convenient to use. This is especially true if you have a lot of values ​​per line to mark up. But the CALL mechanism is pretty slow. For this simple task with two band values, this slows down the solution by more than 5 times.

@echo off
setlocal enableDelayedExpansion

(for /f "delims=, tokens=1,2" %%A in (file.csv) do (
  call Strip0 %%A A
  call Strip0 %%B B
  echo !A!,!B!
))>stripped.csv
exit /b

:strip0  ValueStr  [RtnVar]
::
:: Strip leading zeros from value ValueStr and store the result in vaiable RtnVar.
:: If RtnVar is not specified, then print the result to stdout.
::
for /f "delims=0 tokens=*" %%A in ("%~1") do for /f %%B in ("%%A 0") do (
  if "%~2" equ "" (echo %%B) else set "%~2=%%B"
)
exit /b

      

There is an improved batch macro technology that can encapsulate logic into a macro function without significantly slowing things down. See http://www.dostips.com/forum/viewtopic.php?f=3&t=1827 for background information on batch macros with arguments.

Here is a solution using a batch macro. This is 4 times faster than the CALL method.

@echo off

:: The code to define the macro requires that delayed expansion is disabled.
setlocal disableDelayedExpansion
call :defineStrip0

:: This example requires delayed expansion within the loop
setlocal enableDelayedExpansion
(for /f "delims=, tokens=1,2" %%A in (file.csv) do (
  %strip0% %%A A
  %strip0% %%B B
  echo !A!,!B!
))>stripped.csv
exit /b


:defineStrip0    The code below defines the macro.

:: Define LF to contain a linefeed character (0x0A)
set ^"LF=^

^" The above empty line is critical - DO NOT REMOVE

:: Define a newline with line continuation
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"

::%strip0%  ValueStr  [RtnVar]
::
::  Strip leading zeros from string ValueStr and return the result in variable StrVar.
::  If RtnVar is not specified, then print the result to stdout.
::
set strip0=%\n%
for %%# in (1 2) do if %%#==2 (setlocal enableDelayedExpansion^&for /f "tokens=1,2" %%1 in ("!args!") do (%\n%
  for /f "delims=0 tokens=*" %%A in ("%%1") do for /f %%B in ("%%A 0") do (%\n%
    endlocal^&if "%%2" equ "" (echo %%B) else set "%%2=%%B"%\n%
  )%\n%
)) else set args=
exit /b

      

+5


source


EDIT : my first code was wrong! This version works fine:



@echo off
setlocal EnableDelayedExpansion

(for /f "tokens=1,2 delims=," %%a in (file1.csv) do (
   call :leftZero %%a first=
   call :leftZero %%b second=
   echo !first!,!second!
))>stripped.txt
goto :EOF

:leftZero
set num=%1
:nextZero
   if "%num:~0,1%" neq "0" goto endLeftZero
   set num=%num:~1%
goto nextZero
:endLeftZero
set %2=%num%
exit /B

      

+1


source







All Articles