WindowsBatchScripting_C

Built-in commands

下列命令都是命令解释器built-in的, 不能被改变. 有时候, 因为它们要求获取internal命令解释器的数据结构, 或者修改命令解释器process自身的属性.

Overview

CommandDescription
ASSOC将一个扩展名和文件类型(FTYPE)关联起来
BREAK设置或清除扩展的 CTRL+C检查
CALL从batch程序中调用另一个batch程序
CD, CHDIR显示或设置当前目录
CHCP显示或设置 active code的页码
CLS清除屏幕
COLOR设置控制台背景和前景色
COPY赋值文件
DATE显示及设置系统日期
DEL, ERASE删除一个或更多文件
DIR列出文件和子目录
ECHO显示消息, 或者开关命令echo
ELSEbatch程序中的条件处理
ENDLOCAL在batch文件中, 结束环境局部化的变化
EXIT退出 cmd.exe程序(命令解释器)
FOR对文件集合中的每个文件运行指定的命令
FTYPE设置文件类型
IFbatch程序中的条件处理
MD, MKDIR创建目录
MOVE移动文件
PATH设置或修改 PATH环境变量
PAUSE让command session暂停用户输入
POPD从directory stack中弹出的驱动盘符和目录, 回到上个目录
PROMPT设置或修改在等待输入时显示的string
PUSHD将当前目录压入stack, 进入新的目录
RD / RMDIR移除目录
REM注释命令. 和双冒号(::)不同, 这个命令可以执行
REN / RENAME重命名文件或目录
SET设置或显式 shell环境变量
SETLOCAL为bacth文件创建一个子环境
SHIFT将 batch参数前移
START用多个options启动一个程序
TIME显式或设置系统时钟
TITLE改变窗口标题
TYPE将文件内容打印到控制台
VER显式命令处理器, 操作系统的版本
VERIFY验证文件拷贝被正确执行
VOL显式当前volume label(卷标)

ASSOC

将文件类型(FTYPE)和一个扩展名关联起来, 显式已存的关联, 或删除一个关联. 参见 FTYPE
ex.
- assoc
列出所有读关联, 格式为 <file extension>=<file type>, e.g. “.pl=Perl” or “.xls=Excel.Sheet.8”.
- assoc | find ".doc"
列出所有包含”.doc”子串的关联.

assoc at ss64.com
assoc at Microsoft
Making Python scripts run on Windows without specifying “.py” extension at stackoverflow

BREAK

基于Windows NT的版本中, 什么都不做, 为了和MS DOS兼容.

break at Microsoft

CALL

从一个batch程序中调用另一个batch, 或者调用由单个batch程序的子程序. 对于调用子程序, 参见 Function.

call at ss64.com
call at Microsoft

CD

进入不同的路径, 或者显式当前路径. 但是如果用了另一个drive letter(驱动器号), 它不会自动切换到另一个drive或volume中.

ex.
- cd
- cd C:\Program Files
- cd \Program Files
- cd Documents
- cd %USERPROFILE%
- cd /d C:\Program Files
进入 C:驱动器路径, 即使C:不是当前驱动器
- C: & cd C:\Program Files.
进入 C:驱动器路径, 即使C:不是当前驱动器
- cd ..
进入父目录. 如果是在 root目录, 就什么都不做.
- cd ..\..
进入上两层的父目录.
- C: & cd C:\Windows\System32 & cd ..\..\Program Files
使用 “..”在目录树中上下浏览

中间有space的path无需引号包围.

cd at ss64.com
chdir at Microsoft

CHDIR

CD的同义词.

CLS

清空屏幕.

COLOR

设置控制台的前景和背景颜色.

ex.
- color f9
白色背景蓝色前景
- color
恢复原始颜色设置

color at ss64.com
color at Microsoft

COPY

拷贝文件, 参见 MOVE.

ex.
- copy F:\File.txt
将文件拷贝到当前目录, 假设当前目录不是 F:\
- copy "F:\My File.txt"
同上, 文件名有空格的时候用引号包围.
- copy F:\*.txt
将 F:\目录下以 .txt结尾的文件拷贝到当前目录, 假设当前目录不是 F:\
- copy F:\*.txt .
功能同上.
- copy File.txt
发出错误信息, File.txt无法自己拷贝到自己.
- copy File1.txt File2.txt
将 File1.txt拷贝到 File2.txt, 在用户确认后(或者从batch脚本执行), 就覆盖 File2.txt.
- copy File.txt "My Directory"
将File.txt 拷贝到 “My Directory” 目录, 假设目录存在.
- copy Dir1 Dir2
将 Dir1目录下的所有文件拷贝到 Dir2, 假设Dir1和Dir2都是目录. 不会拷贝Dir1下嵌套的子目录下的文件.
- copy *.txt *.bak
将当前目录下的 *.txt文件, 拷贝一份以 “bak”作为结尾, 代替 “txt”.

copy at ss64.com
copy at Microsoft

DEL

文件删除. 小心使用, 特别是在和通配符(wildcard)组合的时候. 只删除文件, 不会删除目录, 参见 RD以及 “del /?”

e.x.
- del File.txt
- del /s *.txt
递归地删除文件包括嵌套目录下的, 不过保留目录; 暴力删除所有匹配的文件, 不会提出确认请求.
- del /p /s *.txt
同上, 但是会对每个文件都提出确认请求.

del at ss64.com
del at Microsoft

DIR

列出目录的内容, 提供一个范围选项.

e.x.
- dir
列出当前文件夹下的文件和文件夹, 除了隐藏文件和系统文件;
uses a different manner of listing if DIRCMD variable is non-empty and contains switches for dir.
- dir D:
- dir /b C:\Users
- dir /s
列出目录的内容以及递归地列出子目录.
- dir /s /b
列出目录的内容以及递归地列出子目录, 每个文件一行, 显示文件或目录的完整路径.
- dir *.txt
列出 .txt扩展名的文件
- dir /a
包含隐藏文件和系统文件.
- dir /ah
只列出隐藏文件.
- dir /ad
只列出目录. /A后面还可以跟 S, I, R, A and L.
- dir /ahd
只列出隐藏目录.
- dir /a-d
只列出文件, 忽略目录.
- dir /a-d-h
只列出非隐藏的文件, 忽略目录.
- dir /od
根据最后修改的日期来为文件和文件夹排序. 后面还可以跟 N (by name), E (by extension), S (by size), G (folders first)
- dir /o-s
根据文件大小降序排列; 对于文件夹的影响比较模糊.
- dir /-c /o-s /a-d
根据文件大小降序排列, 通过/-C, 忽略千位分隔符(thousands separator), 不包含文件夹
- dir /s /b /od
列出目录内容以及递归的子目录, 根据最后修改日期来排列文件. 次序根据每个目录来排列; 搜索到的文件不会以一个完整集合来排序.

DATE

显示或设置日期; 显示的方式依赖于country设置. 也可以使用 “echo %DATE%”显示日期.
当日期以 ISO format显示, 如”2000-01-28”: 因为日期格式依赖于country设置, 因此会比较麻烦.

  • 如果假定格式为”Mon 01/28/2000”
    • set isodate=%date:~10,4%-%date:~4,2%-%date:~7,2%
  • 如果有 WMIC, 下面的代码可以不依赖 locale:
    • for /f %i in ('wmic os get LocalDateTime') do @if %i lss a if %i gtr 0 set localdt=%i
      set isodate=%localdt:~0,4%-%localdt:~4,2%-%localdt:~6,2%
    • 要在batch中使用上面的代码, 将 %i 改为 %%i, 移除 if前面的 @.
  • 如果安装了Perl.
    • for /f %i in ('perl -MPOSIX -le "print strftime '%Y-%m-%d', localtime"') do @set isodate=%i

How to get current datetime on Windows command line, in a suitable format for using in a filename? at stackoverflow

ECHO

显示消息, 以及将command echoing打开或关闭.

e.x.
- echo on
- @echo off
- echo Hello
- echo "hello"
引号也显示.
- echo %PATH%
显示 PATH变量的内容
- echo Owner ^& son
使用caret (^) 来转义 ampersand (&), 就能显示 &号.
- echo 1&echo 2&echo 3
显示3个string, 每个都会跟一个newline.
- echo %random%>>MyRandomNumbers.txt
看起来是输出随机数到 MyRandomNumbers.txt, 实际上对于0-9的数字并非如此, 在 >>前的数字代表重定向的channel. 参见 Redirection.
- echo 2>>MyRandomNumbers.txt
重定向标准错误到文件中, 而不是显示 2.
- (echo 2)>>MyRandomNumbers.txt
显式一个小数字 (这里是2), 重定向结果.
- >>MyRandomNumbers.txt echo 2
另一个方式来显式一个小数字, 重定向结果.

显示一个不带 newline的string需要一些小技巧:
- set <NUL /p=Output of a command:
显示”Output of a command:”. 下一个命令的输出会在 “:”后面立刻显示;
- set <NUL /p=Current time: & time /t
在 “Current time: ” 后面显示 “time /t”的输出.
- (set <NUL /p=Current time: & time /t) >tmp.txt
同上, 将两个命令的输出重定向到文件中.

ELSE

if exist file.txt (
  echo The file exists.
) else (
  echo The file does not exist.
)

参见 IF.

ENDLOCAL

将从 SETLOCAL开始的local环境变量终止. 可以用来创建子程序: 参见Function.

ERASE

DEL的同义词.

EXIT

Exits the DOS console or, with /b, only the currently running batch or the currently executed subroutine. If used without /b in a batch file, causes the DOS console calling the batch to close.
退出DOS控制台, 或者带 /b, 只退出当前运行的batch或当前执行的subroutine(子程序). 如果不带 /b, 在batch文件中, 会引起调用batch的 DOS控制台关闭.

e.x.
- exit
- exit /b

FOR

对一系列的值进行迭代, 执行命令.

下面的例子中, %i在command line使用, %%i在batch中使用.

e.x.
- for %%i in (1,2,3) do echo %%i
- 在batch中, 显示 1,2,3,. 在batch中的command必须使用双百分号(double percent sign).
- 下列例子是用在command line中, 所以只需一个百分号, 而且会包含 “@”以防止repetitive (重复的)显示.
- for %i in (1,2,3) do @echo %i
- 在command line中显式 1,2,3
- for命令尝试将item解释为文件名, 以及包含通配符的模式(pattern).
- 不过, 在item和文件名不匹配的时候它不会报错.
- for %i in (1,2,a*d*c*e*t) do @echo %i
除非正好有文件符合第三个pattern, 否则会显示1,2, 丢弃第三个item.
- for %i in (1 2,3;4) do @echo %i
显示1, 2, 3, 4. 使用了混合的分隔符.
- for %i in (*.txt) do @echo %i
显示位于当前文件夹下 .txt后缀的文件名.
- for %i in ("C:\Windows\system32\*.exe") do @echo %i
显示和pattern匹配的文件名.
- for /r %i in (*.txt) do @echo %i
对于在当前文件夹包含嵌套文件夹下符合后缀名 .txt的文件, 显示包含全路径的文件名.
- for /d %i in (*) do @echo %i
显示当前文件夹下所有文件夹名.
- for /r /d %i in (*) do @echo %i
当前文件夹包括嵌套文件夹下, 显示包含全路径的文件名.
- for /r %i in (*) do @if %~zi geq 1000000 echo %~zi %i
对于当前文件夹以及子文件夹下的每个文件, size大于等于 1,000,000 bytes的就输出文件size和文件全路径. 对于语法 %~zi, 参见Percent tilde.
- for /l %i in (1,1,10) do @echo %i
从1到10显示数字. (start, step, end)
- for /f "tokens=*" %i in (list.txt) do @echo %i
显示文件中的每一行.
- for /f "tokens=*" %i in (list1.txt list2.txt) do @echo %i
显示文件中的每一行.
- for /f "tokens=*" %i in (*.txt) do @echo %i
声明都不做. 文件名不支持通配符.
- for /f "tokens=1-3 delims=:" %a in ("First:Second::Third") do @echo %c-%b-%a
- 将string解析为token, 用 “:” 分界(delimite).
- 引号表示string不是文件名.
- 第二三个token存储在 %b和 %c, 即使 %b和 %c 在命令”do”之前没有显式地提及.
- 两个连续冒号(colon)被视为一个分隔符, %c不是 “”而是 “Third”.
- 做了一些类似其他操作系统中cut命令的工作.
- for /f "tokens=1-3* delims=:" %a in ("First:Second::Third:Fourth:Fifth") do @echo %c-%b-%a: %d
同上, 不过 4th 和5th items 由%d 捕获, 格式为”Fourth:Fifth”, 包含分隔符.
- for /f "tokens=1-3* delims=:," %a in ("First,Second,:Third:Fourth:Fifth") do @echo %c-%b-%a: %d
多种分隔符(delimiter).
- for /f "tokens=1-3" %a in ("First Second Third,item") do @echo %c-%b-%a
默认delimiter是space和 tab. 它们与用来分隔传给batch的参数的separator不同.
- for /f "tokens=*" %i in ('cd') do @echo %i
显示command result的每一行.
- for /f "tokens=*" %i in ('dir /b /a-d-h') do @echo %~nxai
当前文件夹下的非隐藏文件, 显示带文件名的文件attribute. %~nxai使用了 Percent tilde的语法.
- for /f "usebackq tokens=*" %i in (dir /b /a-d-h) do @echo %~nxai
同上, 不过对命令使用反引号backquote character () 包围.
-
for /f “tokens=*” %i in (‘tasklist ^| sort ^& echo End’) do @echo %i
命令中的 pipe和 ampersand必须使用caret (^)来转义.
-
(for %i in (1,2,3) do @echo %i) > anyoldtemp.txt
要将整个loop的输出重定向, 要将loop放入括号中. 否则重定向会绑定到loop体, loop每个新的迭代会覆盖前一次迭代的结果.
-
for %i in (1,2,3) do @echo %i > anyoldtemp.txt`
和上例相关. 显示不加括号的情况.

Continue:
要跳到loop的下一个迭代以 emulate之后的语句, 很多语言可以使用 goto, 可以将loop体放入子程序:

for %%i in (a b c) do call :for_body %%i
exit /b

:for_body
    echo 1 %1
    goto :cont
    echo 2 %1
  :cont
exit /b

如果直接在for loop内使用 goto, goto的使用会破坏 loop bookkeeping, 下面的命令会失败:

for %%i in (a b c) do (
    echo 1 %%i
    goto :cont
    echo 2 %%i
  :cont
    echo 3 %%i
)

FTYPE

显示或设置文件类型的命令; 参见 ASSOC.

ex.
- ftype
列出所有命令和可执行的文件类型之间的联系, e.g. Perl="C:\Perl\bin\perl.exe" "%1" %*
- ftype | find "Excel.Sheet"
只列出包含 “Excel.Sheet”的联系.

Making Python scripts run on Windows without specifying “.py” extension at stackoverflow

GOTO

跳转到一个label.

ex.

goto :mylabel
echo Hello 1
REM Hello 1 never gets printed.

:mylabel
echo Hello 2
goto :eof

echo Hello 3
REM Hello 3 never gets printed. Eof is a virtual label standing for the end of file.

Note: 在 for loop中的 goto会让 cmd忘记 loop, 即使 label是在相同的loop体中.

IF

条件执行命令. 参见 IF /?

基本检测(elementary test):
- exist <filename>
- <string>==<string>
- <expression1> equ <expression2> – equals
- <expression1> neq <expression2> – not equal
- <expression1> lss <expression2> – less than
- <expression1> leq <expression2> – less than or equal
- <expression1> gtr <expression2> – greater then
- <expression1> geq <expression2> – greater than or equal
- defined <variable>
- errorlevel <number>
- cmdextversion <number>

对于每个elementary test, 都可以使用”not”. 这里没有像 AND, OR, etc. 之类的操作来组合 elementary tests.

/I 开关使得 ==equ 比较忽略大小写.

ex.

if not exist %targetpath% (
  echo Target path not found.
  exit /b
)

ex.

  • if not 1 equ 0 echo Not equal
  • if 1 equ 0 echo A & echo B
    什么都不做, 两个echo命令都受 if影响.
  • if not 1 equ 0 goto :mylabel
  • if not a geq b echo Not greater
  • if b geq a echo Greater
  • if b geq A echo Greater in a case-insensitive comparison
  • if B geq a echo Greater in a case-insensitive comparison
  • if 0 equ 00 echo Numerical equality
  • if not 0==00 echo String inequality
  • if 01 geq 1 echo Numerical comparison
  • if not "01" geq "1" echo String comparison
  • if 1 equ 0 (echo Equal) else echo Unequal
    Notice then部分用括号包围起来才能正常工作.
  • if not a==A echo Case-sensitive inequality
  • if /i a==A echo Case-insensitive equality
  • if /i==/i echo This does not work
  • if "/i"=="/i" echo Equal 使用引号来确保 /i的字面含义.

MD

创建新目录. 同义词 MKDIR, 参见 RD.
ex.
- md Dir
当前目录下创建1个目录
- md Dir1 Dir2
当前目录下创建2个目录
- md "My Dir With Spaces"
当前目录下创建一个名字包含space的目录

MKDIR

MD同义词.

从Windows Vista版本开始, 可以创建一个 symbolic link (软链接)或其他类型的 link.

MOVE

将文件或目录移动到其他目录, 或者rename(重命名)它们. 参见 REN.

ex.
- move File1.txt File2.txt
将File1.txt 重命名为 File2.txt, 覆盖 File2.txt.
- move File.txt Dir
将 File.txt移到 Dir目录, 假设 File,txt是个文件, Dir是个目录; 如果覆盖的条件满足, 会覆盖目标文件 Dir\a.txt.
- move Dir1 Dir2
重命名目录, Dir1 –> Dir2, 假设Dir1 是个目录而 Dir2不存在.
- move Dir1 Dir2
将目录Dir1 移到 Dir2, 结果是 Dir2\Dir1, 假设两个目录都存在.
- move F:\File.txt
文件移到当前目录.
- move F:\*.txt
将F:\目录下所有以 .txt结尾的文件移到当前目录, 假设当前目录不是F:\

PATH

显示或设置PATH环境变量.

PAUSE

Prompt(提示)用户等待下一个输入.

POPD

进入directory stack中弹出的磁盘或目录. directory stack用PUSHD装填.

PROMPT

可以改变或重设 cmd.exe的 prompt(提示符). 它会设置 PROMPT环境变量的值.

C:\>PROMPT MyPrompt$G

MyPrompt>CD
C:\

MyPrompt>PROMPT
C:\>

PROMPT命令将提示符设为”MyPrompt>”. CD显示当前目录为 “C:\”. 使用不带参数的 PROMPT把提示符设回目录路径.

PUSHD

将当前目录压入directory stack, 使它可以被 POPD获取, 如果带参数, 就进入此目录, 而且此目录作为压入的参数.

RD

移除目录. 参见同义词 RMDIR和 反义词MD. 默认情况只有空目录可以被移除.

ex.
- rd Dir1
- rd Dir1 Dir2
- rd "My Dir With Spaces"
- rd /s Dir1
移除 Dir1包括所有的文件以及子目录, 会有一次确认请求, 通过后进行移除操作. 要在递归删除嵌套文件夹时为每个文件弹出确认请求, 使用 DEL带上 /s开关.
- rd /q /s Dir1
同上, 无需确认.

REN

重命名文件和目录.

ex.
- ren filewithtpyo.txt filewithtypo.txt
- ren *.cxx *.cpp

How does the Windows RENAME command interpret wildcards?, superuser.com

RENAME

REN同义词.

REM

在batch文件中注释(remark), 防止注释内容被执行.

ex.

REM A remark that does not get executed
echo Hello REM This remark gets displayed by echo
echo Hello & REM This remark gets ignored as wished
:: This sentence has been marked as a remark using double colon.

REM一般放在一行开头. 如果放在一个命令后面, 是无法工作的, 除非前置了ampersand(&).

RMDIR

RD同义词.

SET

显示或设置环境变量. 使用 /P开关, 要求用户输入, 将结果存储到变量中. 使用 /A开关, 表现为简单的算术运算, 结果存储到变量中.
使用string赋值, 必须确保在等号前后没有space; set name = Peter无法工作, set name=Peter则正确.

ex.
- set
显示一个环境变量的列表.
- set HOME
显示名字以”HOME”开头的环境变量的值.
- set MYNUMBER=56
- set HOME=%HOME%;C:\Program Files\My Bin Folder
- set /P user_input=Enter an integer:
- set /A result = 4 * ( 6 / 3 )
把计算的结果设置给变量. 参见 Calculation.

SETLOCAL

在batch文件中使用, 使得环境变量的改变只对当前batch文件有效. 当离开batch文件, 什么都不会变.
可以使用 ENDLOCAL来结束. 退出batch文件会自动调用 end local. 可以用来创建子程序: 参见 Function.

另外,可以打开delayed expansion: setlocal EnableDelayedExpansion. delayed expansion 由包围在exclamation marks(感叹号)中的变量名构成, 在执行到它的位置后, 被其值所替换, 而不会在更早的时间点被替换.

e.g.在脚本中使用 delayed expansion, 打印文件第一行中指定的数字. 提供类似一些操作系统中的命令”head”的功能.

@echo off

call :myhead 2 File.txt
exit /b

:: Function myhead
:: ===============
:: %1 - lines count, %2 - file name
:myhead
setlocal EnableDelayedExpansion
set counter=1
for /f "tokens=*" %%i in (%2) do ( 
  echo %%i
  set /a counter=!counter!+1
  if !counter! gtr %1 exit /b
)
exit /b

EnableDelayedExpansion at ss64.com

SHIFT

将batch文件参数一起偏移, 但不影响 %*.
e.g. 如果 %1=Hello 1, %2=Hello 2, %3=Hello 3, 在SHIFT后, %1=Hello 2, %2=Hello 3, 但 %* 还是 “Hello 1” “Hello 2” “Hello 3”.

—TBC—
—YCR—

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值