# windows脚本入门3-字符串及其他细节

# 字符串

# 引号与字符串

在批处理中,除了关键词外其余单词都被处理成字符串,带空格的字符串比如"hello world!"建议用""括起来,这样可以在大部分引用其值得时候省掉在变量再加""。有兴趣的同学可以运行下下面的代码:

@echo off
set info=hello world
echo %info%
if "hello world"==%info% echo they are equal 1
if "hello world"=="%info%" echo they are equal 2 
set info="hello world"
if "hello world"==%info% echo they are equal 3
set info=hello
if hello==%info% echo they are equal 4
pause
1
2
3
4
5
6
7
8
9
10

# 字符串的截取与替换

截取的语法:

%变量名:~位置n,长度m%

比如:

%money:~2,3%

表示从money变量的第二位开始截取三个字符串

如果位置为正数则从左边数第n位,为负数则表示从右边数第n位。

如果长度为正数则表示从位置开始保留m位字符,如果长度为负数则表示从右边数舍弃m位字符。

替换的语法:

%变量名:待替换的字符串=要替换成的字符串%

如果要替换成的字符串为空,那么表示要删除待替换的字符串。

如果要替换成的字符串前面加*,表示替换第一次出现的该字符及其前面的所有字符。

实例:

@echo off
set info=hello world
echo 截取从第2位置开始3个字符"%info:~2,3%"
echo 截取从第2位置开始到倒数第2个字符"%info:~2,-2%"
echo 截取从倒数第8位置开始3个字符"%info:~-8,3%"
echo 截取从倒数第8位置开始到倒数第3个字符"%info:~-8,-3%"

echo ————————————————————
set info=hello world
echo 替换前的值: "%info%" 
set info2=%info:world=xie% 
echo 替换后的值: "%info2%"

set info="hello world"
echo 替换前的值: %info%
set info2=%info:world=xie% 
echo 替换后的值: %info2% 

echo ————————————————————
echo 去掉world字符串:%info:world=%
echo 使用通配符\*替换指定字符串及前面的字符串:%info:*or=hi %
pause
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 实战-在批处理中显示当前时间:

@echo off
set nowTime=%date:~0,4%-%date:~5,2%-%date:~8,2% %time:~0,2%:%time:~3,2%:%time:~6,2%
echo %nowTime%
pause
1
2
3
4

# 实战-去除字符串左边或右边的空格:

@echo off
setlocal EnableDelayedExpansion
set str= hi  
echo "%str%"

:rightSpace
if "%str:~-1%"==" " (
	set str=%str:~0,-1%
	goto rightSpace
)

:leftSpace
if "%str:~0,1%"==" " (
	set str=%str:~1%
	goto rightSpace
)


echo "%str%"
pause
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 注释

rem在回显打开状态是会显示出来的,但是::不管回显是否打开都不显示:

REM 这是一个注释 REM
:: 这是一个注释 ::
@echo off
echo ——————————
REM 这是一个注释 REM
:: 这是一个注释 ::
set num=1 rem hello
echo %num%
echo helloworld rem this is a test
pause
1
2
3
4
5
6
7
8
9
10

有一个有意思的现象:

@echo off
if "a"=="a" (
	echo hixie
::————————————
) else (

)
pause
1
2
3
4
5
6
7
8

上边会得到运行结果:此时不应有 )。
无法解释,暂且当成bug吧。

# 特殊字符处理

有一些特殊字符如果要作为普通字符输出的话需要做一些处理:

@echo off
:: 一般的关键字在前面加'^'
echo ^>hi
:: 或者直接使用""引起来
echo ">"
REM echo '>' 不起作用
:: %需要%%
echo %%
pause
1
2
3
4
5
6
7
8
9

# 文件的读写

先建立一个test.txt文本文件

hello world
I am new to you
1
2

实例:

@echo off
for /f "delims=" %%x in (test.txt) do set content=%%x
echo %content%
set /p content2=<test.txt
echo %content2%
echo test world > hi.txt
echo 3>hi.txt
echo 2 > hi.txt
>hi.txt echo heheheh
pause
1
2
3
4
5
6
7
8
9
10

注意使用重定向有0-9个数字。0代表标准输入,1代表标准输出,2代表错误输出。平常我们使用重定向符>默认是1。也就是echo hi > test.txt 只是 echo hi 1> test.txt的缩写。所以echo 3>hi.txt 并不会把3输出到文件而echo 2 > hi.txt 会把2输出到文件。

# 变量延迟

这个概念是我接触批处理后第一次接触到的,挺奇葩的,其他高级语言中有复合语句,比如c有{}语句块,python缩进量相同的为一个语句块。而批处理中for语句,if语句,(),&&,&,||中的语句均为复合语句。而批处理处理复合语句的时候是将这些语句一次读入内存然后进行变量替换。这就导致下面的问题:

@echo off
set info=h0
set info=h1 && echo %info%
set info=h2 & echo %info%
for %%i in (1 2 3) do (
	set info=%%i
	echo %info%
)
pause
1
2
3
4
5
6
7
8
9

要解决上面的问题我们需要使用变量延迟语法,也就是在执行的时候再解析变量而不是在读入一个语句块时提前解析。

# 变量延迟的语法:

setlocal EnableDelayedExpansion
set var=hi
echo !var!
1
2
3

实例:

@echo off
setlocal EnableDelayedExpansion
set info=h0
set info=h1 && echo !info!
set info=h2 & echo !info!
echo ————————————
for %%i in (1 2 3) do (
	set info=%%i
	echo %info%
	echo !info!
)
pause
1
2
3
4
5
6
7
8
9
10
11
12