Если вы готовы использовать гибридную JScript/пакетную утилиту REPL.BAT, то решение может быть столь же просто, как:
type file.csv|repl "0*(\d\d*),0*(\d\d*)" "$1,$2" >stripped.csv
Это не только REPL.BAT решение простое, оно также очень эффективно. Он может обрабатывать большой CSV довольно быстро.
Если у вас должно быть чистое пакетное решение, то здесь используется тот, который не использует CALL или GOTO или замедленное расширение, и он правильно обрабатывает значение 0. Это будет значительно медленнее, чем решение REPL.BAT, но Я думаю, что это наиболее эффективное решение для чистого пакета.
Первый цикл анализирует линию на два значения.
Затем для каждого значения есть еще две петли. Первая строка содержит начальные нули, но также добавляет дополнительное значение 0 после пробела, так что оно всегда возвращает строку, даже если значение равно 0. Последний цикл затем возвращает либо исходное нулевое значение, либо если оно было исключено, потому что оно равно 0, тогда оно возвращает добавленное значение 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
Код для разметки ведущих нулей может быть инкапсулирован в функцию, а затем он станет более удобным в использовании. Это особенно верно, если у вас есть много значений в строке для разметки. Но механизм CALL довольно медленный. Для этой простой задачи с двумя значениями раздеться, это замедляет решение вниз более чем в два раза 5.
@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
Существует продвинутая партия макро метод, который может инкапсулировать логику в макро-функции без значительного замедления вещей вниз. См. http://www.dostips.com/forum/viewtopic.php?f=3&t=1827 для получения справочной информации о пакетных макросах с аргументами.
Это решение, использующее макрос партии. Это в 4 раза быстрее, чем метод CALL.
@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
Ваш код для меня совсем не работает. Я получаю ', * delims = 0" было неожиданным в это время. 'Когда я запускаю его. – aphoria