目录
1. 判断文件夹是否存在。路径:D:\bat,使用脚本判断bat文件夹是否存在。
2. 判断文件是否存在。路径:D:\bat\bat01.bat,检查文件bat01.bat是否存在。
3. 遍历文件夹名。遍历输出D:\bat文件夹下所有文件夹名字
4. 遍历文件名。遍历输出`D:\bat`文件夹下所有文件的名字
5.文件夹重命名。路径:D:\bat\study,study文件夹命名为 study_yyyyMMddHHmmss这个格式
6. 文件重命名。路径:`D:\bat\bat01.bat`,bat01.bat文件命名为`bat01_yyyyMMddHHmmss.bat`格式
7. 复制文件夹。路径:`D:\bat`下面的study文件夹 复制到`D:\batCopy`
8. 复制文件。路径:`D:\bat\bat01.bat`复制到`D:\batCopy`目录下
相信大家在日常开发时,会有接触到脚本,在Windows系统中的脚本,Bat脚本。下面我举出具体例子和实现脚本。
1. 判断文件夹是否存在。路径:D:\bat,使用脚本判断bat文件夹是否存在。
@REM 这个命令关闭了命令提示符窗口中的命令回显,即在执行每一条命令时不会显示命令本身。
@echo off
@REM 这个命令定义了一个名为 file_path 的变量
set "dir_path=D:\bat"
IF EXIST %dir_path% (
echo "Directory exist."
) else (
echo "Directory does not exist."
)
@REM 这个命令用于暂停脚本的执行,等待用户按下任意键才会继续执行后续命令。
pause
@REM 或者是这样,反着来
IF NOT EXIST %dir_path% (
echo "Directory does not exist."
) else (
echo "Directory exist."
)
2. 判断文件是否存在。路径:D:\bat\bat01.bat,检查文件bat01.bat是否存在。
@echo off
set "file_path=D:\bat\bat01.bat"
IF EXIST %file_path% (
echo "File exist."
) else (
echo "File does not exist."
)
pause
@REM 或者是这样,反着来
IF NOT EXIST %file_path% (
echo "Directory does not exist."
) else (
echo "Directory exist."
)
修饰符 | 作用 |
---|---|
%~I | - 删除任何引号("),扩展 %I |
%~fI | - 将 %I 扩展到一个完全合格的路径名 |
%~dI | - 仅将 %I 扩展到一个驱动器号 |
%~pI | - 仅将 %I 扩展到一个路径 |
%~nI | - 仅将 %I 扩展到一个文件名 |
%~xI | - 仅将 %I 扩展到一个文件扩展 |
%~sI | - 扩展的路径只含有短名 |
%~aI | - 将 %I 扩展到文件的文件属性 |
%~tI | - 将 %I 扩展到文件的日期/时间 |
%~zI | - 将 %I 扩展到文件的大小 |
%~$PATH:I | - 查找列在路径环境变量的目录,并将 %I 扩展到找到的第一个完全合格的名称。如果环境变量名未被定义,或者没有找到文件,此组合键会扩展到空字符串 |
修饰符 | 作用 |
---|---|
%~dpI | - 仅将 %I 扩展到一个驱动器号和路径 |
%~nxI | - 仅将 %I 扩展到一个文件名和扩展名 |
%~fsI | - 仅将 %I 扩展到一个带有短名的完整路径名 |
%~dp$PATH:I | - 搜索列在路径环境变量的目录,并将 %I 扩展到找到的第一个驱动器号和路径。 |
%~ftzaI | - 将 %I 扩展到类似输出线路的 DIR |
3. 遍历文件夹名。遍历输出D:\bat文件夹下所有文件夹名字
@echo off
@REM 这个命令开启了延迟变量扩展,它允许在代码块内使用 ! 来访问变量的延迟更新值。
setlocal enabledelayedexpansion
set "dir_path=D:\bat"
@REM `/d`是只遍历目录.`%%i`表示当前迭代的文件夹对象.
for /d %%d in ("%dir_path%\*") do (
set "dir_name=%%~nxd"
echo Directory Name: !dir_name!
echo.
)
@REM 这个命令结束延迟变量扩展的作用域。
endlocal
pause
%%d这个符号,他可以是a~z,或者A~Z这26个字符都行。
for循环中的遍历,需要使用setlocal enabledelayedexpansion和endlocal这个来延迟变量扩展
4. 遍历文件名。遍历输出`D:\bat`文件夹下所有文件的名字
@echo off
setlocal enabledelayedexpansion
set "dir_path=D:\bat"
for %%F in ("%dir_path%\*") do (
@REM 获取文件名(不包括扩展名)
set "fileName=%%~nF"
@REM 获取完整的文件名(包括扩展名,就是.txt、.bat)
set "fullFileName=%%~nxF"
echo File Name: !fileName!
echo Full File Name: !fullFileName!
echo.
)
endlocal
pause
5.文件夹重命名。路径:D:\bat\study,study文件夹命名为 study_yyyyMMddHHmmss这个格式
@echo off
set "dir_path=D:\bat"
set "timestamp=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%"
rename "%dir_path%\study" "study_"%timestamp%
pause
6. 文件重命名。路径:`D:\bat\bat01.bat`,bat01.bat文件命名为`bat01_yyyyMMddHHmmss.bat`格式
@echo off
set "dir_path=D:\bat"
set "timestamp=%date:~0,4%%date:~5,2%%date:~8,2%%time:~0,2%%time:~3,2%%time:~6,2%"
for %%F in ("%dir_path%\bat01.bat") do (
ren "%%F" "%%~nF"_"%timestamp%""%%~xF"
)
pause
7. 复制文件夹。路径:`D:\bat`下面的study文件夹 复制到`D:\batCopy`
@echo off
set "dir_path=D:\bat"
set "dir_copy_path=D:\batCopy"
xcopy "%dir_path%\study" "%dir_copy_path%\study" /E /I /Y
pause
/E
: 递归地复制目录及其子目录的内容
/I
: 如果目标不存在,将目标视为目录而不是文件。
/Y
: 确认覆盖现有的目标文件而不提示xcopy也能修改复制过去的文件夹名字。如:xcopy "%dir_path%\study" "%dir_copy_path%\study001" /E /I /Y
8. 复制文件。路径:`D:\bat\bat01.bat`复制到`D:\batCopy`目录下
@echo off
set "file_path=D:\bat\bat01.bat"
set "dir_copy_path=D:\batCopy"
copy "%file_path%" "%dir_copy_path%\"
pause
copy 命令也能在复制的时候把复制文件名字更换为其他。
如:
copy "%file_path%" "%dir_copy_path%\bat01_rename.bat"
9. 删除文件夹。删除文件夹D:\bat\study
@echo off
set "dir_path=D:\bat\study"
rmdir /s /q "%dir_path%"
pause
/s
: 这是rmdir
命令的一个选项(开关)。/s
表示删除目录时要递归地删除其所有子目录和文件。换句话说,它会删除目录及其内容。
/q
: 这也是rmdir
命令的一个选项。/q
表示在删除目录时不要进行确认提示。默认情况下,rmdir
会要求用户确认是否要删除每个文件或目录,但使用/q
选项后,将自动进行删除操作而不询问用户。
10.删除文件。删除文件D:\bat\bat01.bat
@echo off
set "file_path=D:\bat\bat01.bat"
del "%file_path%"
pause
11.两个文本,一个文本追加到另外一个文本后面。
这个文本复制,思路两种:一种是直接追加进入文本尾部。另外一种是先把需要追加的文本输出或者复制到另外一个临时文本,再把复制文本追加进入临时文本,再替换追加文本。
for /f 此文本循环 for 有个需要注意的点,这个循环遍历只会识别有内容的行,空行会被过滤掉,追加进去的后果就是,追加的内容没有空行,和原本内容不符合。我的解决方案如下:
@echo off
setlocal enabledelayedexpansion
set "txt01_path=D:\bat\test01.txt"
set "txt02_path=D:\bat\test02.txt"
for /f "usebackq" %%F in (`type "%txt02_path%" ^| findstr /N ".*"`) do (
set "line=%%F"
set "line=!line:*:=!"
echo.!line!>> %txt01_path%
)
endlocal
pause
for /f "usebackq" %%F in (`
type "%txt02_path%" ^| findstr /N ".*"`) do (
: 这是一个for
循环,用于逐行处理%txt02_path%
文件中的内容。
type "%txt02_path%"
: 这个部分使用type
命令来将%txt02_path%
文件的内容输出到命令行。
^|
: 这是一个管道操作符,它将前一个命令的输出传递给后面的命令。
findstr /N ".*"
: 这个部分使用findstr
命令来对前一个命令的输出进行处理。findstr
是用于在文本中查找字符串的命令,/N
参数表示在输出中包含行号,而".*"
表示匹配任意字符(.
)零次或多次(*
)的正则表达式,这实际上匹配了每一行的内容。
set "line=%%F"
: 在循环内部,将当前行的内容保存在名为line
的变量中。
set "line=!line:*:=!"
: 这一步通过变量替换操作来去掉行号。每行的内容在之前的操作中已经包含了行号,例如:行号:实际内容
,这一步操作将会去除行号部分,只保留实际内容部分。
echo.!line!>> %txt01_path%
: 最后,将处理后的行内容写入到%txt01_path%
文件中,使用echo
命令。需要注意第7部的echo.这个`.`点号,如果不加点号,内容里面会输出`ECHO 处于关闭状态。`
12.书写一个死循环,true继续,false关闭
@echo off
:loop
set /p context="Place you input (Y/N)"
if /i "%context%"=="Y" (
echo "write your logic"
goto loop
) else if /i "%context%"=="N" (
echo "skip loop"
goto end
) else (
echo "your input error"
goto loop
)
:end
pause
13.循环输入Y/N还有个问题,需要将其稍加修改下。
@echo off
setlocal enabledelayedexpansion
set file_path=%~dp0%
for /d %%i in (%file_path%\bat\*) do (
set file_name=%%~nxi
:loop
set /p context="Do you change file !file_name! input (Y/N)"
if /i "%context%"=="Y" (
echo "write !file_name! your logic"
) else if /i "%context%"=="N" (
echo "skip loop"
) else (
echo "your input error"
goto loop
)
)
endlocal
pause
上面这个脚本大致意思是,我遍历磁盘bat文件夹下所有文件夹,%%~nxi是拿到当前循环的文件夹名字,输入Y时,就对这个文件夹做逻辑操作,输入N时,就跳过,输入非Y/N时就在重新输入值。
上面脚本的问题就在于,若正常输入Y或N时脚本是正常运行;但是输入非Y/N后,goto到上面,之后再正常输入Y/N时,就会发生执行了当前这个循环,执行完当前循环后,这个循环直接break跳出,后面的循环直接不做了。
我对上述问题的解决方法是使用choice命令,让用户只能按下 "Y" 键或 "N" 键来作出选择。
@echo off
setlocal enabledelayedexpansion
set file_path=%~dp0%
for /d %%i in (%file_path%\bat\*) do (
set file_name=%%~nxi
choice /c YN /M "Do you want to change `!file_name!`?"
set "choice=!errorlevel!"
if !choice!==1 (
echo "write your logic"
) else if !choice!==2 (
echo "skip loop"
)
)
endlocal
pause
1. choice /c YN /M "Do you want to change `!file_name!`?"
set "choice=!errorlevel!"
2. set /p context="Do you change file !file_name! input (Y/N)"
区别在于:
choice
用于获取二选一的简单选择,而set /p
允许用户输入任何文本。choice
的用户界面更加明确,因为它只允许特定的选择。而set /p
可以接受更多种类的输入,但也需要更多的用户自我控制来确保输入的是有效的。