增量部署代码利用批处理命令按原始结构复制指定的文件

Posted 黄洪波写点东西的地方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了增量部署代码利用批处理命令按原始结构复制指定的文件相关的知识,希望对你有一定的参考价值。

在实际的代码部署过程中,不可能所有项目都是按照全量部署,毕竟本地代码可能比需要上线的代码更往前进了一步,有部分代码不需要在本次部署。

若使用了SVN或者git这种代码管理工具,则直接可以考虑利用钩子进行自动化部署,可自行查找相关资料,此种自动化部署不在本次讨论的范围内。

 

利用批处理的思路:

1.通过SVN获取本次需要提交的代码的完整路径;

2.替换其中的指定字符获取需要部署的class完整路径;

3.利用md命令和copy递归创建目录路径及复制文件;

4.统计源列表中涉及的文件数量和复制的文件数量,检查是否有遗漏。

 

注意,需要以ANSI格式编码bat脚本。

 

1.之前直接使用的copy,自己写了个遍历,后来发现一个xcopy的命令,可以直接复制子目录空目录啥的,并且可以根据需要排除指定文件,需要在脚本的同级目录创建objectslist.cfg和exclude.cfg.

此脚本比前后一个脚本处理objectslist中包含文件夹目录的情况效率更高。

建议使用xcopy,效率比copy高太多了。

xcpfile.zip

@echo off&setlocal enabledelayedexpansion 

REM AUTHOR:黄洪波
REM DATE:20171027
REM Version:1.0
REM 根据自己的环境设置目标根目录和classes长度
rem v1.1 使用 /exclude:exclude.txt 来排除指定文件


REM 使用方法,在copy.bat同级目录下建立文件objectslist.cfg,将需要部署的文件的源文件(java,xml)按行放入cfg文件中
REM 本方法默认cfg中为文件列表,未处理文件夹的情况
REM 配合SVN使用,效果极好,SVN COMMIT,右键选择需要部署的文件,COPY FULL PATHS
REM 执行xcpfile.bat命令
REM 使用xcopy配合参数来达到递归拷贝文件夹的目的
REM 需要排除的文件名称放入exclude.cfg中


REM 获取当前日期 YYYYMMDD
set datestr=%date:~0,4%%date:~5,2%%date:~8,2%
rem echo !datestr!

rem 设置目标根目录
set tarpath=C:\\Work\\项目\\部署\\!datestr!\\install\\code\\oaf\\
REM 根据自己的C:\\JDeveloper\\jdevhome\\jdev\\myclasses\\,myclasses目录的路径长度进行设置
set lgth=38

REM 全局变量
set len=
set splitstr=

set filecount=0
set copycount=0

rem 判断目标根目录是否存在
if not exist !tarpath! (
md !tarpath!
)

rem 将被排除的文件名称组成字符串,findstr加入""则是判断字符串,不加则是通过文件进行判断
set execludestr="
for /f "tokens=*" %%i in (exclude.cfg)     do (
set str=%%i
rem echo str !str!
set execludestr=!execludestr! !str!
)
set execludestr=!execludestr!"
rem echo execludestr !execludestr!



echo 正在复制...
call:xcpfile
echo 执行检查...
rem 检查数量
call:checkfilecount

goto:eof

:xcpfile
rem 遍历cfg文件中的每一行
for /f "tokens=*" %%i in (objectslist.cfg)     do (
rem cfg中的文件数量
set /a filecount=!filecount!+1
rem 获取行文本
set str=%%i
rem echo str !str!
rem 替换行文本中的myprojects为myclasses
set temp=!str:myprojects=myclasses!
rem echo temp !temp!
rem 替换行文本中的java为class
set temp1=!temp:java=class!
rem 设置class及xml文件完整文件路径
set classpath=!temp1!
rem echo classpath !classpath!

rem 得到classpath的长度
call:length !classpath!
rem classpath的完整长度赋值给length1
set length1=!len!
rem echo length1 is !length1!


rem 获取以\\拆分classpath,获取最后一个字符
call:splitstring !classpath!
rem echo splitstr is !splitstr!

rem 获取classpath中\\后的字符长度
call:length !splitstr!
rem 将其赋值给length2
set length2=!len!
rem echo length2 is !length2!

rem 判断是否为目录
if exist !classpath!\\ (
rem echo !classpath! is dir
rem 获取类路径
call set clapth=%%classpath:~!lgth!%%
rem echo echo clapth dir !clapth!
) else (
rem echo !classpath! is file
rem 做减法运算
rem 此处的38需要根据本地的路径长度做调整
set /a leng=!length1!-!length2!-!lgth!
rem echo leng !leng!
rem 获取类路径
call set clapth=%%classpath:~!lgth!,!leng!%%
rem echo clapth !clapth!
)

set targetpath=!tarpath!!clapth!
rem echo targetpath !targetpath!

rem 判断目标根目录是否存在
if not exist !targetpath! (
md !targetpath!
rem copy !classpath!  !targetpath!
REM /S 不复制空目录
call xcopy /Y /Q /S /exclude:exclude.cfg !classpath!  !targetpath! >nul
set /a copycount=!copycount!+1
) else (
rem 复制文件
rem copy !classpath!  !targetpath!
xcopy /Y /Q /S /exclude:exclude.cfg !classpath!  !targetpath! >nul
set /a copycount=!copycount!+1
)

)
rem echo filecount !filecount!
rem echo copycount !copycount!
rem echo objectslist.cfg中的文件数量为!filecount!个,本次共成功导入!copycount!个。

goto:eof

rem 获取字符串长度
:length
set "str=%~1"
for /l %%i in (0,1,200) do if "!str:~%%i,1!"=="" set strlen=%%i && goto :end
:end 
rem echo 字符串长度为 %strlen% 
set len=%strlen%
rem echo 长度为 %len% 
goto:eof

rem 按\\拆分字符串
:splitstring
set string=%~1
set split=
:split
for /f "tokens=1,* delims=\\" %%i in ("%string%") do (
rem  echo %%i
  set string=%%j
  set split=%%i
)
if not "%string%"=="" goto split
rem echo split !split!
set splitstr=%split%
goto:eof




rem 检查文件数量
:checkfilecount

set notexistscount=0
set errorstr=

for /f "tokens=*" %%i in (objectslist.cfg)     do (
set sourcestr=%%i
set temp=!sourcestr:myprojects=myclasses!
rem 替换行文本中的java为class
set temp1=!temp:java=class!
rem 设置class及xml文件完整文件路径
set sourcepath=!temp1!

call set clapth=%%sourcepath:~!lgth!%%
set targetpath=!tarpath!!clapth!

rem echo sourcepath !sourcepath! targetpath !targetpath!

rem 源路径为文件夹
if exist !sourcepath!\\ (
    set sourcecount=0
    rem 加入2^>nul解决目标文件夹中没有文件时,屏幕显示找不到文件的问题
    for /f "delims=" %%b in (\'dir !sourcepath! /b/s/a-d 2^>nul ^| findstr /v !execludestr! \' ) do ( 
        set /a sourcecount+=1
    )
    
    rem echo sourcepath !sourcepath! sourcecount !sourcecount!
    
    set targetcount=0
    rem 加入2^>nul解决目标文件夹中没有文件时,屏幕显示找不到文件的问题
    for /f "delims=" %%b in (\'dir !targetpath! /b/s/a-d 2^>nul ^| findstr /v !execludestr! \' ) do ( 
        set /a targetcount+=1
    )
    rem echo targetpath !targetpath! targetcount !targetcount!
    
    
    if !sourcecount! NEQ !targetcount! (
        rem echo errorstr !errorstr!
        set errorstr=!errorstr! !sourcepath!中有文件复制失败
    )
) else (
    rem echo file targetpath !targetpath!
    if not exist !targetpath! (
        rem echo errorstr !errorstr!
        set errorstr=!errorstr! !sourcepath!复制失败
    ) 
)

)

if "%errorstr%" =="" (
    echo 经检查,已完整复制objectslist中的文件至 !tarpath! 。
) else (
    for %%i in (!errorstr!) do echo %%i
)

goto:eof

 

 

方式2,使用copy,需要在脚本的同级目录创建objectslist.cfg,自己写的遍历子目录。

cpfile.zip

@echo off&setlocal enabledelayedexpansion 

REM AUTHOR:黄洪波
REM DATE:20171027
REM Version:1.0
REM 根据自己的环境设置目标根目录和classes长度
REM v1.4 若objectlist.cfg包含目录,则copy该目录及其子目录下的所有文件
REM v1.5 设置需要需要排除的文件


REM 使用方法,在copy.bat同级目录下建立文件objectslist.cfg,将需要部署的文件的源文件(java,xml)按行放入cfg文件中
REM 本方法默认cfg中为文件列表,未处理文件夹的情况
REM 配合SVN使用,效果极好,SVN COMMIT,右键选择需要部署的文件,COPY FULL PATHS
REM 执行cpfile.bat命令

REM 获取当前日期 YYYYMMDD
set datestr=%date:~0,4%%date:~5,2%%date:~8,2%
rem echo !datestr!

rem 设置目标根目录
set tarpath=C:\\Work\\项目\\部署\\!datestr!\\install\\code\\oaf\\
REM 根据自己的C:\\JDeveloper\\jdevhome\\jdev\\myclasses\\,myclasses目录的路径长度进行设置
set lgth=38

rem 设置需要排除的文件,多个文件用空格分隔,如果不存在需要排除的文件,则用"*"
set execludestr="server.xml bc4j.xcfg"
REM set execludestr="*"

REM 全局变量
set len=
set splitstr=

set filecount=0
set copycount=0

rem 判断目标根目录是否存在
if not exist !tarpath! (
md !tarpath!
)


echo 正在复制...
rem 遍历cfg文件中的每一行
for /f "tokens=*" %%i in (objectslist.cfg)     do (
set str=%%i
call:openlist !str!
)

echo 执行检查...
rem 检查数量
call:checkfilecount

goto:eof


:openlist
set filestr=%~1
if exist !filestr!\\ (
rem echo  dir !filestr!
rem 列出文件夹下所有子目录及文件,并排除server.xml bc4j.xcfg
rem dir /b/s/a/d 列出所有子目录及文件 
rem dir /b/s/a-d 仅列出当前目录及子目录的文件
for /f "delims=" %%b in (\'dir !filestr! /b/s/a-d ^| findstr /v !execludestr! \') do (   
rem echo %%b
call:openlist %%b
rem 输出至当前目录的t.txt文件中
rem echo %%b  >>t.txt
)  
rem call:openlist !filestr!
) else (
rem 文件路径直接copy
call:copyfile !filestr!
)
goto:eof

:copyfile
rem 遍历cfg文件中的每一行
rem cfg中的文件数量
set /a filecount=!filecount!+1
rem echo 获取行文本
set str=%~1
rem 替换行文本中的myprojects为myclasses
set temp=!str:myprojects=myclasses!
rem 替换行文本中的java为class
set temp1=!temp:java=class!
rem 设置class及xml文件完整文件路径
set classpath=%temp1%
rem echo !classpath!
rem 得到classpath的长度
call:length !classpath!
rem classpath的完整长度赋值给length1
set length1=!len!
rem echo length1 is !length1!

rem 获取以\\拆分classpath,获取最后一个字符
call:splitstring !classpath!
rem echo splitstr is !splitstr!

rem 获取classpath中\\后的字符长度
call:length !splitstr!
rem 将其赋值给length2
set length2=!len!
rem echo length2 is !length2!

rem 做减法运算
rem 此处的38需要根据本地的路径长度做调整
set /a leng=!length1!-!length2!-!lgth!
rem echo leng !leng!

rem 获取类路径
rem 此处的38需要根据本地的路径长度做调整
call set clapth=%%classpath:~!lgth!,!leng!%%
rem echo clapth !clapth!

set targetpath=!tarpath!!clapth!
rem echo targetpath !targetpath!

rem 判断目标根目录是否存在
rem 2>NUL 表示命令执行失败或否的时候 不显示
rem 1>NUL 表示命令执行正确或是的时候 不显示(同>NUL)
if not exist !targetpath! (
md !targetpath!
copy !classpath!  !targetpath! >nul
set /a copycount=!copycount!+1
) else (
rem 复制文件
copy !classpath!  !targetpath! >nul
set /a copycount=!copycount!+1
)


rem echo filecount !filecount!
rem echo copycount !copycount!
rem echo objectslist.cfg中的文件数量为!filecount!个,本次共成功导入!copycount!个。

goto:eof


rem 获取字符串长度
:length
set "str=%~1"
for /l %%i in (0,1,200) do if "!str:~%%i,1!"=="" set strlen=%%i && goto :end
:end 
rem echo 字符串长度为 %strlen% 
set len=%strlen%
rem echo 长度为 %len% 
goto:eof

rem 按\\拆分字符串
:splitstring
set string=%~1
set split=
:split
for /f "tokens=1,* delims=\\" %%i in ("%string%") do (
rem  echo %%i
  set string=%%j
  set split=%%i
)
if not "%string%"=="" goto split
rem echo split !split!
set splitstr=%split%
goto:eof


rem 检查文件数量
:checkfilecount

set notexistscount=0
set errorstr=

for /f "tokens=*" %%i in (objectslist.cfg)     do (
set sourcestr=%%i
set temp=!sourcestr:myprojects=myclasses!
rem 替换行文本中的java为class
set temp1=!temp:java=class!
rem 设置class及xml文件完整文件路径
set sourcepath=!temp1!

call set clapth=%%sourcepath:~!lgth!%%
set targetpath=!tarpath!!clapth!

rem echo sourcepath !sourcepath! targetpath !targetpath!

rem 源路径为文件夹
if exist !sourcepath!\\ (
    set sourcecount=0
    rem 加入2^>nul解决目标文件夹中没有文件时,屏幕显示找不到文件的问题
    for /f "delims=" %%b in (\'dir !sourcepath! /b/s/a-d 2^>nul ^| findstr /v !execludestr! \' ) do ( 
        set /a sourcecount+=1
    )
    
    rem echo sourcepath !sourcepath! sourcecount !sourcecount!
    
    set targetcount=0
    rem 加入2^>nul解决目标文件夹中没有文件时,屏幕显示找不到文件的问题
    for /f "delims=" %%b in (\'dir !targetpath! /b/s/a-d 2^>nul ^| findstr /v !execludestr! \' ) do ( 
        set /a targetcount+=1
    )
    rem echo targetpath !targetpath! targetcount !targetcount!
    
    rem 等价
    rem if !sourcecount! == !targetcount!
    rem if !sourcecount! equ !targetcount! (
    rem     set notexistscount=0
    rem     echo 数量相等
    rem ) else (
    rem     echo 数量不相等
    rem )
    if !sourcecount! NEQ !targetcount! (
        rem echo errorstr !errorstr!
        set errorstr=!errorstr! !sourcepath!中有文件复制失败
    )
) else (
    rem echo file targetpath !targetpath!
    if not exist !targetpath! (
        rem echo errorstr !errorstr!
        set errorstr=!errorstr! !sourcepath!复制失败
    ) 
    rem else (
    rem     set errorstr=!errorstr! !sourcepath!复制失败
    rem )
)

)

rem echo errorstr !errorstr!
rem 
rem set lengtherrstr=0
rem set len=0
rem call:length !errorstr!
rem set lengtherrstr=!len!
rem echo lengtherrstr !lengtherrstr!
rem 
rem if lengtherrstr neq 0 (
rem     echo lengtherrstr is not null    
rem     echo lengtherrstr is !lengtherrstr!
rem     for %%i in (!errorstr!) do echo %%i
rem ) else (
rem     echo 经检查,已完整复制objectslist中的文件。
rem )

if "%errorstr%" =="" (
    echo 经检查,已完整复制objectslist中的文件至 !tarpath! 。
) else (
    for %%i in (!errorstr!) do echo %%i
)



goto:eof

 

以上是关于增量部署代码利用批处理命令按原始结构复制指定的文件的主要内容,如果未能解决你的问题,请参考以下文章

java按指定后缀复制文件并保留原始文件夹路径

利用批处理命令复制指定文件到指定目录下

windows下批量部署简易脚本

25.cp命令

如何让批处理按创建时间删除某文件夹下的文件

利用Linux命令行进行文本按行去重并按重复次数排序