使用批处理对现有文件进行版本控制 [英] Versioning up existing files using batch

查看:80
本文介绍了使用批处理对现有文件进行版本控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@echo off

:prep
cls
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
:for /l %A in (1,1,100) do copy "C:\some folder\file.ext" "C:\some folder\file-%%A.ext"
set choice=

:: test to see if directory exists
if EXIST "../delivery_%mydate%.txt" (
    goto overwrite
) else (
    goto start
)

:overwrite
echo.
echo delivery note already exists - continue?
set /p choice='y / n ?'
if '%choice%'=='' ECHO "%choice%" is not valid please try again
if '%choice%'=='y' goto start
if '%choice%'=='n' goto end
echo.

:start
echo.
for /l %A in (1,1,100) do copy "C:\some folder\delivery_%mydate%.ext" "C:\some folder\delivery_%mydate%.ext"
echo Choose the following:
echo 1. Directories
echo 2. Files
echo 3. quit
echo.
set /p choice=
if '%choice%'=='1' goto directory
if '%choice%'=='2' goto file
if '%choice%'=='3' goto end
cls
ECHO "%choice%" is not valid please try again
goto start

:directory
dir /ad /on /b > ../delivery_%mydate%.txt
echo.
goto checksuccess

:file
dir /a-d /on /b > ../delivery_%mydate%.txt
echo.
goto checksuccess

:checksuccess

我需要在上面创建的此批处理文件中添加一行代码.我需要此代码来将现有文件保存到更高版本而不删除前一个文件.这也需要嵌入到我创建的代码中.例如,它将开始像filev001filev002等那样保存它们.

I need to add a line of code to this batch file I have created above. I need this code to save an existing file to a higher version without deleting the previous one. This will also need to be embedded into the code I created. For example it will start saving them like: filev001, filev002, etc.

推荐答案

1.编写批处理文件的一些一般建议

在命令提示符窗口help中执行时输出命令列表.建议在批处理文件中使用环境变量和标签,而不是字符串,这也不是命令.可能,但不建议.

1. Some general advice for writing batch files

A list of commands is output on executing in a command prompt window help. It is advisable to use in batch files for environment variables and labels not a string which is also a command. It is possible, but not advisable.

start是用于在单独进程中启动应用程序的命令.因此,最好使用例如Begin而不是start作为标签.

start is a command to start an application in a separate process. So it is better to use for example Begin instead of start as label.

choice是用于选择的命令,与使用set /P相比,单字符选择更好.因此,最好使用例如UserChoice而不是仅使用choice作为环境变量名称.

choice is a command for a choice which is better for single character choices than using set /P. So it is better to use for example UserChoice instead of just choice as environment variable name.

最好使用echo/代替echo.输出空行.原因由DosTips论坛主题 ECHO解释.未能输入文本或空白行-而是使用ECHO/.

It is better to use echo/ instead echo. to output an empty line. The reason is explained by DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/.

使用 C amel C ase可以更容易地读取环境变量名称和标签,并且可以区分大小写,并且在必要时可以在批处理文件中替换,而不是区分大小写在注释和使用echo输出的字符串中也可以作为单词存在的名称/标签.

Environment variable names and labels are easier to read on using CamelCase and can be more easily searched case-sensitive and if necessary replaced in a batch file than a name/label which can exist as word also in comments and in strings output with echo.

关于问题的答案,为什么在命令行上使用'set var = text'后没有显示'echo%var%'的字符串详细解释为什么在将字符串分配给环境变量时,为什么建议在批处理文件中使用语法set "Variable=string value".

The answer on question Why is no string output with 'echo %var%' after using 'set var = text' on command line? explains in detail why the usage of the syntax set "Variable=string value" is recommended in batch files on assigning a string to an environment variable.

Windows上的目录分隔符是反斜杠字符\.斜杠/是Unix/Linux/Mac上的目录分隔符.在Windows上,/用于选项/参数. Windows内核功能通过将内部的/自动更正为\,还支持使用/作为目录分隔符的目录和文件路径.但是仍然建议在路径中的批处理文件\中使用.

The directory separator on Windows is the backslash character \. The slash character / is the directory separator on Unix/Linux/Mac. On Windows / is used for options/parameters. The Windows kernel functions support also directory and file paths with / as directory separator by automatically correcting them to \ internally in path. But it is nevertheless recommended to use in a batch file \ in paths.

rem是批处理文件中用于注释的命令. ::是无效标签,不是真正的注释.开头带有标签的行将被忽略以执行命令.但是标签不能在命令块中使用.因此,建议使用命令rem,因为命令块中的::通常会在执行批处理文件时导致意外行为.

rem is the command for a comment in a batch file. :: is an invalid label and not really a comment. Lines with a label at begin are ignored for command execution. But a label cannot be used in a command block. For that reason it is recommended to use command rem because :: in a command block results often in unexpected behavior on execution of the batch file.

让我们在命令行上查看:

Let us look on the command line:

for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)

date /tfor在后台命令过程中使用命令行cmd.exe /C date /t执行的命令,用于捕获写入标准输出句柄 STDOUT 的该命令过程的输出并处理逐行捕获输出.

date /t is a command which for executes in a background command process with the command line cmd.exe /C date /t for capturing the output of this command process written to standard output handle STDOUT and process the captured output line by line.

这可以优化吗?

是的,因为在命令提示符窗口set /?中运行并从第一页到最后一页读取输出帮助时,可以看到存在环境变量DATE可以扩展到当前日期.因此,无需运行命令date即可将当前日期作为字符串获取.

Yes, because on running in a command prompt window set /? and reading the output help from first to last page it can be read that there is the environment variable DATE which expands to current date. So there is no need to run the command date to get current date as string.

带有选项/t的命令date以Windows 区域和语言设置中为使用的用户帐户定义的格式输出当前日期.在您的情况下,看起来与地区相关的日期格式为MM/dd/yyyy,并且在日期之前以星期几开头(无逗号).我计算机上的日期格式为dd.MM.yyyy,没有工作日.环境变量DATE与命令date /t的输出具有相同的区域依赖性格式.

The command date with option /t outputs the current date in the format defined for the used user account in Windows Region and Language settings. In your case it looks like the region dependent date format is MM/dd/yyyy with the weekday abbreviation at beginning (with no comma) before the date. The date format on my computer is just dd.MM.yyyy without weekday. The environment variable DATE is in same region dependent format as output of command date /t.

因此,也可以使用命令行将格式为ddd, MM/dd/yyyy的与区域相关的日期修改为yyyy-MM-dd:

So the region dependent date in format ddd, MM/dd/yyyy could be also modified to yyyy-MM-dd using the command line:

for /F "tokens=2-4 delims=/, " %%a in ("%DATE%") do set "MyDate=%%c-%%a-%%b"

也可以使用字符串替换:

It is also possible to use string substitution:

set "MyDate=%DATE:~-4%-%DATE:~-10,2%-%DATE:~-7,2%"

在运行set /?时的帮助输出还解释了字符串替换,并在
上阅读了答案 %date是什么:〜-4,4 %% date:〜-10,2 %% date:〜-7,2%_ %time:〜0.2 %% time:〜3.2%平均值?

String substitution is also explained by help output on running set /? and read the answer on
What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean?

但是,如果yyyy-MM-dd是当前日期的所需日期格式,而与所使用的用户帐户的区域设置无关,则建议使用命令行

But if yyyy-MM-dd is the wanted date format for current date independent on region settings of the used user account is advisable to use the command lines

for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "MyDate=%%I"
set "MyDate=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%"

与区域无关的解决方案实际上比上述命令行要慢得多. 为什么%date%在作为计划任务执行的批处理文件中产生不同的结果?但这具有区域独立的巨大优势.

This region independent solution is really much slower than the above command lines. It is explained in detail by the answer on Why does %date% produce a different result in batch file executed as scheduled task? But it has the big advantage of being region independent.

不建议在单个字符选择中使用set /P variable=prompt,因为

The usage of set /P variable=prompt is not recommended for a single character choice because

  • 用户可以直接按 RETURN ENTER 而不输入任何内容,从而导致variable保留其当前值,或者如果未定义在命令行;
  • 用户可能会输入错误,并按下例如 Shift + 2 而不是仅仅按 2 (在德语键盘上)输入"作为字符串,使用set /P的大多数批处理文件由于在评估用户输入的下一个命令行上的语法错误而中断;
  • 用户可以输入任何内容来代替要求输入的字符之一,包括在下一个命令行中导致删除文件和文件夹的字符串.
  • the user can just hit RETURN or ENTER without entering anything at all resulting in variable keeping its current value or still not being defined if not defined before set /P command line;
  • the user can make a typing mistake and presses for example Shift+2 instead of just 2 resulting (on German keyboard) to enter " as string which most batch files using set /P breaks because of a syntax error on next command line evaluating the user input;
  • the user can enter anything instead of one of the characters asked for including strings which on next command line results in deletion of files and folders.

如果可能的话,解决方案使用命令choice(取决于Windows版本). choice等待命令选项中指定的字符被按键,并在按下其中一个键后立即继续.并且choice退出,并具有批处理文件中指定的列表中按下的字符的索引.将此退出代码分配给ERRORLEVEL,然后可以在命令块中对其进行下一步评估,而无需使用延迟扩展,或者直接在单个goto指令中使用.

The solution is using the command choice if that is possible (depends on Windows version). choice waits for the key press of a character specified in the command options and immediately continues after one of these keys is pressed. And choice exits with the index of the pressed character in list as specified in batch file. This exit code is assigned to ERRORLEVEL which can be evaluated next also within a command block without using delayed expansion or used directly in a single goto instruction.

这是重写的批处理文件:

Here is the rewritten batch file:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem set "Folder=C:\some folder"
set "Folder=F:\Temp\Test"

:Prepare
cls
rem Get current date region independent in format yyyy-MM-dd.
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "MyDate=%%I"
set "MyDate=%MyDate:~0,4%-%MyDate:~4,2%-%MyDate:~6,2%"

set "FileNumber=0"
for %%I in ("%Folder%\file-*.ext") do call :GetFileNumber "%%~nI"
goto IncrementNumber

rem Subroutine to find out highest file number without using delayed
rem environment variable expansion for number range 0 to 2147483647.

rem Numbers starting with 0 are interpreted as octal number in number
rem comparison which makes it necessary to remove leading 0 from the
rem number string get from file name starting with 5 characters.

:GetFileNumber
set "Number=%~1"
set "Number=%Number:~5%

:RemoveLeadingZero
if "%Number%" == "" goto :EOF
if "%Number:~0,1%" == "0" set "Number=%Number:~1%" & goto RemoveLeadingZero
if %Number% GTR %FileNumber% set "FileNumber=%Number%"
goto :EOF

rem Make sure the file number has at least 3 digits.
:IncrementNumber
set /A FileNumber+=1
if %FileNumber% GEQ 100 goto ExistDelivery
set "FileNumber=00%FileNumber%"
set "FileNumber=%FileNumber:~-3%"

rem Test to see if file exists already.
:ExistDelivery
if not exist "..\delivery_%MyDate%.txt" goto Begin
echo/
%SystemRoot%\System32\choice.exe /C YN /N /M "Delivery note already exists, continue (Y/N)? "
if errorlevel 2 goto :EOF

:Begin
set "FileName=file-%FileNumber%.ext"
copy "%Folder%\file.ext" "%Folder%\%FileName%" >nul
echo/
echo Choose the following:
echo/
echo    1. Directories
echo    2. Files
echo    3. Quit
echo/
%SystemRoot%\System32\choice.exe /C 123 /N /M "Your choice? "
if errorlevel 3 goto :EOF
if errorlevel 2 goto GetFileList

dir * /AD /ON /B >"..\delivery_%MyDate%.txt"
echo/
goto CheckSuccess

:GetFileList
dir * /A-D /ON /B >"..\delivery_%MyDate%.txt"
echo/

:CheckSuccess
rem More commands.
endlocal

对于我来说,还不清楚整个批处理代码到底是干什么的.

It was not really clear for me what the entire batch code is for at all.

在知道可能的数字范围(例如001100)时,将最高编号的确定写入文件名也将更加容易.所以我写了001002,...,099100101,...,1000,...,2147483647的通用解决方案.

It would have been also easier to write the determination of highest number in a file name on knowing the possible number range like 001 to 100. So I wrote a general solution for 001, 002, ..., 099, 100, 101, ..., 1000, ..., 2147483647.

要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面.

For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /?
  • cls /?
  • copy /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?
  • wmic /?
  • wmic os /?
  • wmic os get /?
  • wmic os get localdatetime /?
  • call /?
  • cls /?
  • copy /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • rem /?
  • set /?
  • setlocal /?
  • wmic /?
  • wmic os /?
  • wmic os get /?
  • wmic os get localdatetime /?

另请参见使用Windows批处理文件的单行包含多个命令的答案,以获取&运算符的解释并阅读有关

See also answer on Single line with multiple commands using Windows batch file for an explanation of & operator and read the Microsoft article about Using command redirection operators.

这篇关于使用批处理对现有文件进行版本控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆