Chr*_*Noe 232 windows hidden-features batch-file
Windows批处理文件有哪些鲜为人知但又重要且有用的功能?
指南:
澄清:我们在这里指的是由cmd.exe处理的脚本,这是WinNT变体的默认值.
(另请参阅:Windows批处理文件:.bat vs .cmd?)
Chr*_*Noe 185
线路延续:
call C:\WINDOWS\system32\ntbackup.exe ^
backup ^
/V:yes ^
/R:no ^
/RS:no ^
/HC:off ^
/M normal ^
/L:s ^
@daily.bks ^
/F daily.bkf
Run Code Online (Sandbox Code Playgroud)
rav*_*ven 150
PUSHD path
Run Code Online (Sandbox Code Playgroud)
转到path指定的目录.
POPD
Run Code Online (Sandbox Code Playgroud)
带你回到你"推"的目录.
Leo*_*Hat 109
不确定这在批处理文件中有多大用处,但在命令提示符下使用它是一个非常方便的命令:
C:\some_directory> start .
Run Code Online (Sandbox Code Playgroud)
这将在"some_directory"文件夹中打开Windows资源管理器.
我发现这是一个很好的节省时间.
Chr*_*Noe 87
我一直觉得很难阅读每行上用关键字标记的评论:
REM blah blah blah
Run Code Online (Sandbox Code Playgroud)
更易于阅读:
:: blah blah blah
Run Code Online (Sandbox Code Playgroud)
Chr*_*Noe 79
变量子串:
> set str=0123456789
> echo %str:~0,5%
01234
> echo %str:~-5,5%
56789
> echo %str:~3,-3%
3456
Run Code Online (Sandbox Code Playgroud)
The*_*edi 72
FOR命令!虽然我讨厌编写批处理文件,但我很感激.
FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k
Run Code Online (Sandbox Code Playgroud)
将解析myfile.txt中的每一行,忽略以分号开头的行,将第2和第3个标记从每行传递给for body,并用逗号和/或空格分隔标记.注意for body语句引用%i获取第二个标记,%j获取第三个标记,%k获取第3个标记之后的所有剩余标记.
您也可以使用它来迭代目录,目录内容等...
Pat*_*uff 60
我没有在REM或:: lines中乱丢脚本,而是在每个脚本的顶部执行以下操作:
@echo OFF
goto :START
Description of the script.
Usage:
myscript -parm1|parm2 > result.txt
:START
Run Code Online (Sandbox Code Playgroud)
请注意如何使用管道和重定向字符而不转义它们.
Rea*_*wTo 54
脚本所在的路径(带驱动器):~dp0
set BAT_HOME=%~dp0
echo %BAT_HOME%
cd %BAT_HOME%
Run Code Online (Sandbox Code Playgroud)
小智 49
已经提到了%~dp0片段,但实际上还有更多内容:〜之后的字符定义了提取的信息.
没有字母结果返回补丁文件名称
d - 返回驱动器号
p - 返回路径
s - 返回短路径
x - 返回文件扩展名
因此如果从c:\ Temp执行下面的脚本test.bat\long dir name \文件夹,
@echo off
echo %0
echo %~d0
echo %~p0
echo %~dp0
echo %~x0
echo %~s0
echo %~sp0
Run Code Online (Sandbox Code Playgroud)
你得到以下输出
Run Code Online (Sandbox Code Playgroud)test c: \Temp\long dir name\ c:\Temp\long dir name\ .bat c:\Temp\LONGDI~1\test.bat \Temp\LONGDI~1\
如果参数像
测试c:\ temp\mysrc\test.cpp
一样传递到脚本中,则可以使用%1变量完成相同的操作.
但是%0扩展的结果取决于位置!
在批处理的"顶层",它扩展为当前批处理文件名.
在函数(调用)中,它扩展为函数名称.
@echo off
echo %0
call :test
goto :eof
:test
echo %0
echo %~0
echo %~n0
Run Code Online (Sandbox Code Playgroud)
输出是(批处理文件以myBatch.bat启动)
myBatch.bat
:test
:test
myBatch
Run Code Online (Sandbox Code Playgroud)
Fer*_*cio 43
通过使用CALL,EXIT/B,SETLOCAL和ENDLOCAL,您可以使用局部变量实现子例程.
例:
@echo off
set x=xxxxx
call :sub 10
echo %x%
exit /b
:sub
setlocal
set /a x=%1 + 1
echo %x%
endlocal
exit /b
Run Code Online (Sandbox Code Playgroud)
这将打印
11
xxxxx
Run Code Online (Sandbox Code Playgroud)
即使:sub修改x.
pax*_*blo 42
偷偷摸摸的技巧等待N秒(不是cmd.exe的一部分,但因为它附带Windows而不是额外的软件),请参阅ping行.你需要N + 1 ping,因为第一次ping没有延迟.
echo %time%
call :waitfor 5
echo %time%
goto :eof
:waitfor
setlocal
set /a "t = %1 + 1"
>nul ping 127.0.0.1 -n %t%
endlocal
goto :eof
Run Code Online (Sandbox Code Playgroud)
Chr*_*Noe 37
逃离"管道":
echo ^| ^< ^> ^& ^\ ^^
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 31
能够运行命令并处理输出(如bash中'$()'的反引号).
for /f %i in ('dir /on /b *.jpg') do echo --^> %i
Run Code Online (Sandbox Code Playgroud)
如果文件名中有空格,请使用:
for /f "tokens=*" %i in ('dir /on /b *.jpg') do echo --^> %i
Run Code Online (Sandbox Code Playgroud)
nzp*_*mad 30
创建一个空文件:
> copy nul filename.ext
Run Code Online (Sandbox Code Playgroud)
aph*_*ria 28
隐藏命令重定向到> nul 2>&1的所有输出.
例如,即使您重定向到> nul,某些命令行程序也会显示输出.但是,如果您将输出重定向到下面的行,则所有输出都将被抑制.
PSKILL NOTEPAD >nul 2>&1
Run Code Online (Sandbox Code Playgroud)
编辑:请参阅忽略命令的输出以获取有关其工作原理的说明.
rav*_*ven 25
PAUSE
Run Code Online (Sandbox Code Playgroud)
停止执行并显示以下提示:
Press any key to continue . . .
有用的,如果你想通过双击它在Windows资源管理器运行批处理,并希望见到实际的输出,而不是只是一个命令行窗口中闪光.
pax*_*blo 25
相当于bash(和其他shell)
echo -n Hello # or
echo Hello\\c
Run Code Online (Sandbox Code Playgroud)
输出" Hello
"没有尾随换行符.一个cmd hack来做到这一点:
<nul set /p any-variable-name=Hello
Run Code Online (Sandbox Code Playgroud)
set /p
是一种提示用户输入的方法.它发出给定的字符串然后等待(在同一行,即没有CRLF),以便用户键入响应.
<nul
只需管道对set /p
命令的空响应,因此最终结果是发出的提示字符串.(由于空的响应,使用的变量保持不变.)
问题是:输出一个前导等号是不可能的,并且在Vista上领先的空白字符被删除,但不是在XP上.
Sql*_*CID 18
设置环境变量时搜索和替换:
> @set fname=%date:/=%
Run Code Online (Sandbox Code Playgroud)
...从用于时间戳文件名的日期中删除"/".
和子串...
> @set dayofweek=%fname:~0,3%
Run Code Online (Sandbox Code Playgroud)
Chr*_*Noe 17
整数算术:
> SET /A result=10/3 + 1
4
Run Code Online (Sandbox Code Playgroud)
doe*_*man 16
命令分隔符:
cls & dir
copy a b && echo Success
copy a b || echo Failure
Run Code Online (Sandbox Code Playgroud)
在第二行,&&仅在第一个命令成功时运行.
在第3行,||之后的命令 仅在第一个命令失败时运行.
Rea*_*wTo 14
快速将Unicode文本文件(16位/字符)转换为ASCII DOS文件(8位/字符).
C:\> type unicodeencoded.txt > dosencoded.txt
Run Code Online (Sandbox Code Playgroud)
作为奖励,如果可能,正确映射字符.
Fer*_*cio 14
如果块结构:
if "%VS90COMNTOOLS%"=="" (
echo: Visual Studio 2008 is not installed
exit /b
)
Run Code Online (Sandbox Code Playgroud)
pax*_*blo 12
变量的延迟扩展(带有子串以便进行测量):
@echo off
setlocal enableextensions enabledelayedexpansion
set full=/u01/users/pax
:loop1
if not "!full:~-1!" == "/" (
set full2=!full:~-1!!full2!
set full=!full:~,-1!
goto :loop1
)
echo !full!
endlocal
Run Code Online (Sandbox Code Playgroud)
小智 12
不提供太多功能,但您可以将title命令用于几个用途,例如在任务栏中的长脚本上提供状态,或者只是为了增强用户反馈.
@title Searching for ...
:: processing search
@title preparing search results
:: data processing
Run Code Online (Sandbox Code Playgroud)
Mor*_*aos 11
字符串减法的示例date
和time
获取名为"YYYY-MM-DD HH:MM:SS.txt"的文件
echo test > "%date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,2%_%time:~3,2%_%time:~6,2%.txt"
我color
用来指示我的脚本是否成功,失败或需要通过更改文本和背景的颜色来输入.当你有一台机器可以看到你的视线但距离很远时,这确实很有帮助
颜色XY
其中X和Y是从十六进制值0
到F
,其中X -背景,Y -文本中,当X = Y颜色不会改变.
颜色Z.
将文本颜色更改为"Z"并设置黑色背景,"颜色0"将不起作用
用于调用颜色的名称
颜色?
小智 11
没有编辑器方便,需要创建批处理文件?
copy con test.bat
Run Code Online (Sandbox Code Playgroud)
只需键入命令,按Enter键即可获得新行.按Ctrl-Z和Enter关闭文件.
pax*_*blo 10
使用间距和转义字符对输出进行完全控制:
echo. ^<resourceDir^>/%basedir%/resources^</resourceDir^>
Run Code Online (Sandbox Code Playgroud)
小智 9
TheSoftwareJedi已经提到了for命令,但是我会再次提到它,因为它非常强大.
以下以YYYYMMDD格式输出当前日期,我在生成备份目录时使用它.
for /f "tokens=2-4 delims=/- " %a in ('DATE/T') do echo %c%b%a
Run Code Online (Sandbox Code Playgroud)
您可以使用call来稍后评估名称,从而产生一些有用的属性.
call set SomeEnvVariable_%extension%=%%%somevalue%%%
Run Code Online (Sandbox Code Playgroud)
使用call来设置名称取决于其他变量的变量.如果与某些变量命名规则一起使用,则可以使用仔细的命名规则来模拟数组(如数组或字典).在某个值周围的三重%是如此,它将在调用之后和调用set之前评估为由单个%包围的一个变量名.这意味着连续两个%转义为单个%字符,然后它会再次展开它,因此somevalue实际上是一个名称指针.
call set TempVar=%%SomeEnvVariable_%extension%%%
Run Code Online (Sandbox Code Playgroud)
将它与temp变量一起使用以检索该值,然后可以在逻辑中使用该值.当与延迟变量扩展一起使用时,这最有用.
要正确使用此方法,需要启用延迟变量扩展.因为它默认是关闭的,所以最好在脚本中启用它,方法是将其作为第一条指令之一:
setlocal EnableDelayedExpansion
Run Code Online (Sandbox Code Playgroud)
在路径上搜索可执行文件(或者在必要时搜索其他类似路径的字符串):
c:\> for %i in (cmd.exe) do @echo. %~$PATH:i
C:\WINDOWS\system32\cmd.exe
c:\> for %i in (python.exe) do @echo. %~$PATH:i
C:\Python25\python.exe
c:\>
Run Code Online (Sandbox Code Playgroud)
关于使用::
而不是REM
评论:小心!::
是一个CALL标签的特例,其作用类似于注释.当在括号内使用时,例如在FOR或IF循环中,该函数将过早退出.调试非常令人沮丧!
有关完整说明,请访问http://www.ss64.com/nt/rem.html.
(在第一次提到上述内容时添加新答案而不是评论,因为我不值得赞扬:0)
这些天很多人使用GOTO:EOF来终止他们的批处理文件,但你也可以使用EXIT/B来实现这个目的.
使用EXIT/B的优点是你可以在EXIT/B之后添加一个错误级别,它将以错误级别退出.
仍然会为ENDLOCAL使用的行解析局部变量.这允许像下面这样的技巧:
ENDLOCAL & SET MYGLOBAL=%SOMELOCAL% & SET MYOTHERGLOBAL=%SOMEOTHERLOCAL%
Run Code Online (Sandbox Code Playgroud)
这是将结果传输到调用上下文的有用方法.具体来说,一旦ENDLOCAL完成,%SOMELOCAL%就会超出范围,但到那时%SOMELOCAL%已经展开,因此MYGLOBAL在调用上下文中使用局部变量进行分配.
出于同样的原因,如果您决定这样做:
ENDLOCAL & SET MYLOCAL=%MYLOCAL%
Run Code Online (Sandbox Code Playgroud)
您将发现新的MYLOCAL变量实际上是作为常规环境变量而不是您可能想要的本地化变量.
子程序(输出42):
@echo off
call :answer 42
goto :eof
:do_something
echo %1
goto :eof
Run Code Online (Sandbox Code Playgroud)
和子程序返回一个值(输出0,1,2等):
@echo off
setlocal enableextensions enabledelayedexpansion
call :seq_init seq1
:loop1
if not %seq1%== 10 (
call :seq_next seq1
echo !seq1!
goto :loop1
)
endlocal
goto :eof
:seq_init
set /a "%1 = -1"
goto :eof
:seq_next
set /a "seq_next_tmp1 = %1"
set /a "%1 = %seq_next_tmp1% + 1"
set seq_next_tmp1=
goto :eof
Run Code Online (Sandbox Code Playgroud)
小智 5
cmd.exe中的快速编辑模式是我的最爱.这稍微偏离了主题,但是当与命令shell交互时,它可以成为救生员.不,我不是双曲线 - 在你死之前你只会看到一些次数的插入符号 ; 你看得越多,你死得越快.
(你也可以在UI中设置这个,这可能是更好的方法.请参阅注释以获取说明.还有一个很好的单行脚本也可以这样做.)
现在,要复制,只需单击鼠标左键并拖动即可选择并右键单击进行复制.要粘贴,只需右键单击即可.
没有更多的时间^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V ^ V !!!
废话,我想我刚刚杀了一个人.抱歉!
调用集 - 将环境变量扩展到几个级别.
在http://ss64.com/nt/call.html#advanced找到这个从回答另一个SO问题批量文件变量在for循环中初始化
set VarName=Param
set Param=This
call set Answer=%%%Varname%%%
Echo %Answer%
Run Code Online (Sandbox Code Playgroud)
给
set VarName=Param
set Param=This
call set Answer=%Param%
Echo This
This
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
219982 次 |
最近记录: |