整数值的千位分隔符
Thousands separator of an integer value
假设我的批处理文件中有这个:
set var1=12345
而我想在第一个变量(var1)中加上逗号,保存到另一个变量(var2).
这意味着第二个变量(var2)应该有这个值:12,345.
所以如果第一个变量 (var1) 有这个值:123456789,第二个 (var2) 的值必须是 123,456,789 .
有什么想法吗?
编辑:
我不想使用 PowerShell 命令,因为它们对我不起作用。
请写没有 PowerShell。
SET var2=%var1%,5
应该可以胜任。
批处理不是执行这种复杂字符串操作的好语言。对于大多数人,我建议使用 PowerShell 来完成繁重的工作。
for /f %%a in ('powershell -c "'{0:N0}' -f %var1%"') do set var2=%%a
如果您需要一个纯批处理的解决方案,您可以使用更多代码迭代完成。此示例适用于 32 位整数。对于更大的数字或浮点数,请参阅@dbenham 的回答。
thousands.cmd
@echo off
:: in: Integer value (must fit into 32 bits)
:: Out: Prints that value with commas after each 3 digits
setlocal
set /a num = %1
set output=
:: Check for trivial zero case and any non-number string input
if {%num%}=={0} (
echo 0
goto :eof
)
:nextgroup
if %num:-=% LSS 1000 goto :lastgroup
set output=,%num:~-3%%output%
set /a num = %num% / 1000
goto :nextgroup
:lastgroup
set output=%num%%output%
endlocal && echo.%output%
示例:
> thousands.cmd 1000
1,000
> thousands.cmd -876543210
-876,543,210
> thousands.cmd 0
0
> thousands.cmd -512
-512
> thousands.cmd fred
0
set var2=%var1:~0,-3%,%var1:~-3%
纯批处理有点棘手。这是一个有效的解决方案,它利用 :strlen function 来确定字符串的长度。 :showThousands 函数适用于任何整数,无论是正数还是负数,最多将近 8191 位。该函数仅修改可选地以 -
开头的值,然后余数仅由数字组成。
@echo off
setlocal enableDelayedExpansion
for %%N in (
1
12
123
1234
12345
123456
1234567
123456789
1234567890
12345678901234567890
-12345678901234567890
fred
123456.789
) do (
set input=%%N
call :showThousands input output
echo !input! --^> !output!
)
exit /b
:showThousands inVar outVar
setlocal enableDelayedExpansion
set num=!%~1!
set "sign="
if %num:~0,1% equ - (
set "sign=-"
set "num=%num:~1%"
)
for /f "delims=0123456789" %%A in ("%num%") do goto :showThousandsReturn
call :strlen len num
if %len% leq 3 goto :showThousandsReturn
set /a end=len%%3
if %end% equ 0 set /a end=3
set /a start=(len-4)/3*3+end
for /l %%N in (%start% -3 %end%) do set "num=!num:~0,%%N!,!num:~%%N!"
:showThousandsReturn
endlocal & set "%~2=%sign%%num%"
exit /b
:strlen <resultVar> <stringVar>
(
setlocal EnableDelayedExpansion
set "s=!%~2!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
endlocal
set "%~1=%len%"
exit /b
)
-- 输出--
1 --> 1
12 --> 12
123 --> 123
1234 --> 1,234
12345 --> 12,345
123456 --> 123,456
1234567 --> 1,234,567
123456789 --> 123,456,789
1234567890 --> 1,234,567,890
12345678901234567890 --> 12,345,678,901,234,567,890
-12345678901234567890 --> -12,345,678,901,234,567,890
fred --> fred
123456.789 --> 123456.789
又一个!
@echo off
setlocal EnableDelayedExpansion
set "var1=%1"
echo First variable: %var1%
set "var2="
set "sign="
if "%var1:~0,1%" equ "-" set "sign=-" & set "var1=%var1:~1%"
for /L %%i in (1,1,4) do if defined var1 (
set "var2=,!var1:~-3!!var2!"
set "var1=!var1:~0,-3!"
)
set "var2=%sign%%var2:~1%"
echo Second variable: %var2%
如果要增加位数,只需将for
命令中的组数增加到大于4的值即可。
快速简便的解决方案。您可以将其另存为批处理并以您的号码作为参数调用它,或者将其嵌入您正在制作的任何脚本中。
说明:
如果输入 val 大于 999,则将 "newval" 设置为逗号,"val" 的最后三位数字然后 trim val 的最后三位数字。
循环直到 val 不再超过 3 位,转储输出。
setlocal
set val=%1
:loop
if %val% GTR 999 (set newval=,%val:~-3%%newval% & set val=%val:~0,-3%
goto loop
)
echo %val:~-3%%newval%
如果您确实需要处理负数,请改用它。
setlocal
set val=%1
if %val% LSS 0 ( set "sign=-" & set "val=%val:~1%" )
:loop
if %val% GTR 999 (set newval=,%val:~-3%%newval% & set val=%val:~0,-3%
goto loop
)
echo %sign%%val:~-3%%newval%
当然,这不会处理错误的输入,但它简短而有趣。
我知道参加派对有点晚了,但这可能对像我这样迟到的人有用。
此方法采用基本的 SET 替换技术。它还支持带有前导 [-] 符号的负整数。
它是一种静态解决方案,因为它应用了任意最大输入数字大小,但可以对其进行修改以满足要求。
对于那些对性能感兴趣的人,它比 FOR 循环解决方案更快。
:: Sample code is for max 21 (-20) digit numbers
:: For larger numbers increase pad size and extend the "preset commas" instruction
:: with leading " %var1:~-NN,3%, " where NN increments by 3
:: The only limit would seem to be variable VAR2 maximum size
:: Note: no size check nor numeric integrity is applied, if input size exceeds
:: design max top digits are simply lost
rem Left pad input with 20 [max-1] characters of your choice [except comma]
rem 12345678901234567890
set var1=####################%1
rem preset comma separators
set var2=%var1:~-21,3%,%var1:~-18,3%,%var1:~-15,3%,%var1:~-12,3%,%var1:~-9,3%,%var1:~-6,3%,%var1:~-3%
rem remove redundant chars
set var2=%var2:#,=%
set var2=%var2:#=%
rem only needed if -nn negative numbers are to be supported
set var2=%var2:-,=-%
ECHO %1 ==^> %var2%
假设我的批处理文件中有这个:
set var1=12345
而我想在第一个变量(var1)中加上逗号,保存到另一个变量(var2).
这意味着第二个变量(var2)应该有这个值:12,345.
所以如果第一个变量 (var1) 有这个值:123456789,第二个 (var2) 的值必须是 123,456,789 .
有什么想法吗?
编辑:
我不想使用 PowerShell 命令,因为它们对我不起作用。 请写没有 PowerShell。
SET var2=%var1%,5
应该可以胜任。
批处理不是执行这种复杂字符串操作的好语言。对于大多数人,我建议使用 PowerShell 来完成繁重的工作。
for /f %%a in ('powershell -c "'{0:N0}' -f %var1%"') do set var2=%%a
如果您需要一个纯批处理的解决方案,您可以使用更多代码迭代完成。此示例适用于 32 位整数。对于更大的数字或浮点数,请参阅@dbenham 的回答。
thousands.cmd
@echo off
:: in: Integer value (must fit into 32 bits)
:: Out: Prints that value with commas after each 3 digits
setlocal
set /a num = %1
set output=
:: Check for trivial zero case and any non-number string input
if {%num%}=={0} (
echo 0
goto :eof
)
:nextgroup
if %num:-=% LSS 1000 goto :lastgroup
set output=,%num:~-3%%output%
set /a num = %num% / 1000
goto :nextgroup
:lastgroup
set output=%num%%output%
endlocal && echo.%output%
示例:
> thousands.cmd 1000
1,000
> thousands.cmd -876543210
-876,543,210
> thousands.cmd 0
0
> thousands.cmd -512
-512
> thousands.cmd fred
0
set var2=%var1:~0,-3%,%var1:~-3%
纯批处理有点棘手。这是一个有效的解决方案,它利用 :strlen function 来确定字符串的长度。 :showThousands 函数适用于任何整数,无论是正数还是负数,最多将近 8191 位。该函数仅修改可选地以 -
开头的值,然后余数仅由数字组成。
@echo off
setlocal enableDelayedExpansion
for %%N in (
1
12
123
1234
12345
123456
1234567
123456789
1234567890
12345678901234567890
-12345678901234567890
fred
123456.789
) do (
set input=%%N
call :showThousands input output
echo !input! --^> !output!
)
exit /b
:showThousands inVar outVar
setlocal enableDelayedExpansion
set num=!%~1!
set "sign="
if %num:~0,1% equ - (
set "sign=-"
set "num=%num:~1%"
)
for /f "delims=0123456789" %%A in ("%num%") do goto :showThousandsReturn
call :strlen len num
if %len% leq 3 goto :showThousandsReturn
set /a end=len%%3
if %end% equ 0 set /a end=3
set /a start=(len-4)/3*3+end
for /l %%N in (%start% -3 %end%) do set "num=!num:~0,%%N!,!num:~%%N!"
:showThousandsReturn
endlocal & set "%~2=%sign%%num%"
exit /b
:strlen <resultVar> <stringVar>
(
setlocal EnableDelayedExpansion
set "s=!%~2!#"
set "len=0"
for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "len+=%%P"
set "s=!s:~%%P!"
)
)
)
(
endlocal
set "%~1=%len%"
exit /b
)
-- 输出--
1 --> 1
12 --> 12
123 --> 123
1234 --> 1,234
12345 --> 12,345
123456 --> 123,456
1234567 --> 1,234,567
123456789 --> 123,456,789
1234567890 --> 1,234,567,890
12345678901234567890 --> 12,345,678,901,234,567,890
-12345678901234567890 --> -12,345,678,901,234,567,890
fred --> fred
123456.789 --> 123456.789
又一个!
@echo off
setlocal EnableDelayedExpansion
set "var1=%1"
echo First variable: %var1%
set "var2="
set "sign="
if "%var1:~0,1%" equ "-" set "sign=-" & set "var1=%var1:~1%"
for /L %%i in (1,1,4) do if defined var1 (
set "var2=,!var1:~-3!!var2!"
set "var1=!var1:~0,-3!"
)
set "var2=%sign%%var2:~1%"
echo Second variable: %var2%
如果要增加位数,只需将for
命令中的组数增加到大于4的值即可。
快速简便的解决方案。您可以将其另存为批处理并以您的号码作为参数调用它,或者将其嵌入您正在制作的任何脚本中。
说明:
如果输入 val 大于 999,则将 "newval" 设置为逗号,"val" 的最后三位数字然后 trim val 的最后三位数字。
循环直到 val 不再超过 3 位,转储输出。
setlocal
set val=%1
:loop
if %val% GTR 999 (set newval=,%val:~-3%%newval% & set val=%val:~0,-3%
goto loop
)
echo %val:~-3%%newval%
如果您确实需要处理负数,请改用它。
setlocal
set val=%1
if %val% LSS 0 ( set "sign=-" & set "val=%val:~1%" )
:loop
if %val% GTR 999 (set newval=,%val:~-3%%newval% & set val=%val:~0,-3%
goto loop
)
echo %sign%%val:~-3%%newval%
当然,这不会处理错误的输入,但它简短而有趣。
我知道参加派对有点晚了,但这可能对像我这样迟到的人有用。 此方法采用基本的 SET 替换技术。它还支持带有前导 [-] 符号的负整数。 它是一种静态解决方案,因为它应用了任意最大输入数字大小,但可以对其进行修改以满足要求。 对于那些对性能感兴趣的人,它比 FOR 循环解决方案更快。
:: Sample code is for max 21 (-20) digit numbers
:: For larger numbers increase pad size and extend the "preset commas" instruction
:: with leading " %var1:~-NN,3%, " where NN increments by 3
:: The only limit would seem to be variable VAR2 maximum size
:: Note: no size check nor numeric integrity is applied, if input size exceeds
:: design max top digits are simply lost
rem Left pad input with 20 [max-1] characters of your choice [except comma]
rem 12345678901234567890
set var1=####################%1
rem preset comma separators
set var2=%var1:~-21,3%,%var1:~-18,3%,%var1:~-15,3%,%var1:~-12,3%,%var1:~-9,3%,%var1:~-6,3%,%var1:~-3%
rem remove redundant chars
set var2=%var2:#,=%
set var2=%var2:#=%
rem only needed if -nn negative numbers are to be supported
set var2=%var2:-,=-%
ECHO %1 ==^> %var2%