yjqd 发表于 2023-10-19 13:05:58

set命令给数字从小到大排序及set call和 call set


为什么有时要用set call,有时要用call set

11.txt内容如下:
700.00
699
6
9.9899
0.6
9.989891234567
15.34
9.98989123453999
3.4
10

运行下面批处理:
@echo off&setlocal enabledelayedexpansion
for /l %%i in (1,1,4) do set "kong=!kong!#"
for /f "tokens=1,2 delims=." %%i in (11.txt) do (
set p=%%i
set "str=!p!%kong%"
call set "a=!str:~,4!"
call set "a=%%a:!p!=%%"
if not "%%j"=="" (set "_!a!!p!.%%j=a") else set "_!a!!p!=a"
)
echo.
echo.
for /f "delims==_" %%i in ('set _') do (
set "str=%%i"
echo !str:#=!
)
pause>nul


结果为:
0.6
3.4
6
9.98989123453999
9.989891234567
9.9899
10
15.34
699
700.00


另一个批处理:
@echo off&setlocal enabledelayedexpansion
rem 微软小工具PsInfo64.exe
for /f "tokens=1,7,8 delims= " %%a in ('PsInfo64 -d 2^>nul^|findstr "GB"') do (
echo %%a %%b %%c|find "GB">NUL&&if /i not exist %%a\WINDOWS\System32\slmgr.vbs set t=%%b %%a

for /l %%c in (1,1,5) do set "kong=!kong!#"
for /f "tokens=1,2,3 delims=. " %%i in ("!t!") do (
set p=%%i

set "str=!p!%kong%"
set call "a=!str:~,5!"
set call "a=%%a:!p!=%%"

if not "%%j"=="" (set "_!a!!p!.%%j GB %%k=a") else set "_!a!!p! GB %%k=a"
rem set t=
)
)
for /f "tokens=3 delims==_ " %%i in ('set _') do (
set "str=%%i"
)
echo.
echo !str:#=!分区 是排除系统分区后剩余空间最大分区
echo.
pause





车厘子 发表于 2023-10-19 13:42:59

抢占沙发

BEIKING 发表于 2023-10-19 14:00:23

这用法有点高端

Anson4 发表于 2023-10-19 14:48:19

感谢分享!

zz7713243 发表于 2023-10-19 15:52:24

看上去很厉害的样子。感谢分享。

创新科技2015 发表于 2023-10-19 21:52:19

感谢分享!

nttwqz 发表于 2023-10-19 22:13:56

本帖最后由 nttwqz 于 2023-10-19 22:29 编辑

@echo off
pushd %~dp0

::call可用于多重变量嵌套,就像下面这样,但是这样会有一堆%,不易读,你在网上看到好几个call call call call和后面很长一串%就是这种用法。

set var=abc
set abc=456
set n456=1234567890

echo %var%
call echo %%%var%%%
call call echo %%%%n%%%var%%%%%%%
call call set str=%%%%n%%%var%%%%%%%
set str

::相对而言,使用for进行变量嵌套,简单易懂,代码易读,推荐使用。
setlocal enabledelayedexpansion
for %%a in (%var%) do for %%b in (!%%a!) do echo !n%%b!

::call的使用严重会影响效率,比使用外置命令比如findstr影响严重的多的多,尽量不要在for中使用call,除标签模块化外非必要时应减少call的使用
set ta=!time!
for /l %%a in (1 1 10000) do echo %%a
set tb=!time!
title !ta!-!tb!

set ta_=!time!
for /l %%a in (1 1 10000) do call :label %%a
set tb_=!time!
title !ta!-!tb!/!ta_!-!tb_!
pause
exit


:label
    echo %1
goto :eof

set call本假大神认为是错误用法,等于定义了一个call+空格+后面字符的变量,不知道其他真大神是怎么认为的。

变量嵌套可看一下和本坛同服务器的批处理之家的教程
批处理脚本高级编程技巧——变量嵌套

一个批处理效率的帖子
提高批处理代码效率的常用技巧及方案1

nathan6498 发表于 2023-10-19 22:39:22

谢谢分享

softwarezheng 发表于 2023-10-20 09:51:33

感谢

batche 发表于 2023-10-20 12:16:37

set call 在代码的用法是错误的,例如,set call "a=1"实际上是为变量call "a赋值为1"。
你贴的第二段代码还有多处错误。

yjqd 发表于 2023-10-20 14:06:37

本帖最后由 yjqd 于 2023-10-20 14:31 编辑

我还以为是set call起了作用,后来我将两个call分别改为:
set 那又鸟 "a=!str:~,5!"
set 马户 "a=%%a:!p!=%%"
运行结果还是正确的
删除原来下面三项
set "str=!p!%kong%"
set call "a=!str:~,5!"
set call "a=%%a:!p!=%%"
运行结果还是正确的

分析了下此批处理,原来是凑巧,所以经过上述的命令运行结果都正确
因为取得的分区容量的整数部分位数都相同,所以无关乎!a!有无结果

yjqd 发表于 2023-10-20 16:14:47


这下正确了:

@echo off&setlocal enabledelayedexpansion

rem 微软小工具PsInfo64.exe

for /l %%c in (1,1,5) do set "kong=!kong!#"
for /f "tokens=1,7,8 delims= " %%a in ('PsInfo -d 2^>nul^|findstr "GB"') do (
echo %%a %%b %%c|find "GB">NUL&&if /i not exist %%a\WINDOWS\System32\slmgr.vbs set t=%%b %%a
for /f "tokens=1,2,3 delims=. " %%i in ("!t!") do (
set p=%%i

set "str=!p!!kong!"
call set "x=!str:~,5!"            ::此处变量不要设为a,否则,下个语句会有%%a,会被解析为上面紫色处的变量%%a
call set "x=%%x:!p!=%%"
if not "%%j"=="" (set "_!x!!p!.%%j GB %%k=a") else set "_!x!!p! GB %%k=a"
)
)

for /f "tokens=3 delims==_ " %%i in ('set _') do (
set "str=%%i"
)
echo.
echo !str:#=!分区 是排除系统分区后剩余空间最大分区
echo.
pause

junyee 发表于 2023-10-21 16:36:17

setcall 玩了近20年批处理还真头一次见。

call set 是为了新开一个环境用来展开 %var%,这样就可以不用开变量扩展了。

nowayer 发表于 2023-11-16 17:17:42

无犹启动 发表于 2024-2-20 07:36:20

谢谢分享

tilltotell007 发表于 2024-2-20 11:12:17

感谢分享,学习了

wang1126 发表于 2024-2-20 14:51:03

感谢分享!

tilltotell007 发表于 2024-2-20 22:06:10

感谢分享

tilltotell007 发表于 2024-2-21 18:01:01

学习了

yinchilang1 发表于 2024-2-24 13:16:23

谢谢楼主分享
页: [1]
查看完整版本: set命令给数字从小到大排序及set call和 call set