整数值的千位分隔符

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%