如何用新信息修改包含给定字符串的行并将其保存为文本文件

How to modify lines that hold a given string with new information and save it as a text file

我正在修改我们在内部调用@make 函数的批处理文件。我们想在批处理文件中添加一个脚本来检查外部 header 文件,找到带有日期信息的行 (APP_VERSION_DATE) 并用新的日期信息更新那里的信息(我想出了如何获取windows 批次的日期信息,这不是问题)

我知道要遵循哪些步骤,但批处理语法对我来说完全违反直觉,我被卡住了。

这些是我想要遵循的步骤:

1- 逐行浏览 app_version.h 文件(for /f)

2- 查找包含字符串 APP_VERSION_DATE 的行(if findstr...)

3- 删除除 APP_VERSION_DATE

之外的所有内容

4- CONCAT 日期信息 APP_VERSION_DATE 如 APP_VERSION_DATE "23-05-2022"

5- 每隔一行重复一次

6- 将信息传输到新的 header 文件。

7-删除header个文件

8- 将新 header 行重命名为旧行。

set strToFind="app_version_date"
set result="Not Found"
for /f "tokens=2 delims=[]" %%A in ('findstr %strToFind% %filename%') do (
      set result=%%A
      if defined result (
           if  %result%==this is something 
           echo hurra this is it
      ) ELSE echo    
)

这就是我现在所处的位置,显然我离做我想做的事情还很遥远。

我可以制作一个程序,可以在文件中找到给定的字符串并进行更改,但在这种情况下,我想找到包含我正在搜索的字符串的行,删除其余部分并修改它。我想找到字符串所在的行并修改它,而不是字符串本身。这仅仅是因为日期信息如下所示;

#define APP_VERSION_DATE [2022-05-16 12:13]

不会是静态的,并且会随着每次编译尝试而不断变化。

我有这样的东西,但这离我想做的太远了。

任何帮助都会很棒!提前致谢

替换头文件中的date/timeapp_version.h

此任务可以使用以下注释批处理文件:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "HeaderFile=app_version.h"
if not exist "%HeaderFile%" exit /B 20

rem Get current local date/time in format [yyyy-MM-dd HH:mm].
for /F "tokens=1-5 delims=/: " %%G in ('%SystemRoot%\System32\robocopy.exe "%SystemDrive%\|" . /NJH') do set "AppVersionDate=[%%G-%%H-%%I %%J:%%K]" & goto UpdateHeaderFile

rem Let FINDSTR output all lines of the header file with a line number and
rem a colon at the beginning for processing really all lines including the
rem empty lines in the header file and output all lines without the line
rem number and the colon with exception of the line containing the string
rem #define APP_VERSION_DATE which is ignored and instead is output a line
rem defined here with the local date/time determined before. All lines output
rem by the loop are written into a newly created temporary header file.

:UpdateHeaderFile
(for /F delims^=^ eol^= %%I in ('%SystemRoot%\System32\findstr.exe /N "^" "%HeaderFile%" 2^>nul') do (
    set "Line=%%I"
    setlocal EnableDelayedExpansion
    if "!Line:#define APP_VERSION_DATE=!" == "!Line!" (
        echo(!Line:*:=!
    ) else (
        echo #define APP_VERSION_DATE %AppVersionDate%
    )
    endlocal
))>"%HeaderFile%.tmp"

rem Replace the original header file with the temporary header file.
if exist "%HeaderFile%.tmp" move /Y "%HeaderFile%.tmp" "%HeaderFile%" >nul

rem Delete the temporary header file if the command line above failed
rem because of the original header file is read-only or write-protected
rem or currently opened by an application with shared access denied.
if exist "%HeaderFile%.tmp" del "%HeaderFile%.tmp"

endlocal

环境变量HeaderFile可以定义绝对路径或相对路径

请阅读我在 Time is set incorrectly after midnight 上的回答中的 使用 ROBOCOPY 获取当前 date/time 一章,以了解第一个 for /F 的解释命令行。

接下来请阅读我在 上的回答 它详细描述了第二个 for /F 循环,并对附加的 IF 条件进行了小的修改以替换包含字符串 #define APP_VERSION_DATE 且当前为 date/time.

的行

为了了解使用的命令及其工作原理,请打开 command prompt window,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • del /?
  • echo /?
  • endlocal /?
  • exit /?
  • findstr /?
  • goto /?
  • if /?
  • move /?
  • rem /?
  • set /?
  • setlocal /?

另请参阅 single line with multiple commands using Windows batch file 了解无条件命令运算符 & 的解释。


用 date/time

创建头文件 current_date_time.h

如果文件 app_version.h 包含以下行的任何地方,任务可以更容易地完成:

#include "current_date_time.h"

在这种情况下,批处理文件可能只是:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
for /F "tokens=1-5 delims=/: " %%G in ('%SystemRoot%\System32\robocopy.exe "%SystemDrive%\|" . /NJH') do echo #define APP_VERSION_DATE [%%G-%%H-%%I %%J:%%K]>"current_date_time.h"& goto EndBatch
:EndBatch
endlocal

这个批处理文件总是创建新文件 current_date_time.h 只用一行:

#define APP_VERSION_DATE [2022-05-23 18:48]

并且这个单独的预处理器宏定义行被编译成 app_version.h


用当前 date/time

定义预处理器宏 APP_VERSION_DATE

每个 C/C++ 编译器都有一个在命令行上定义预处理器宏的选项,并且可以在命令行上多次使用该选项来定义多个预处理器宏。

例如见:

因此可以使用下面的单个命令行以所需格式定义具有当前 date/time 的环境变量,并在 运行 上引用此环境变量值 C/C++ 编译器带有适当的选项。

 @set "AppVersionDate=" & for /F "tokens=1-5 delims=/: " %%G in ('%SystemRoot%\System32\robocopy.exe "%SystemDrive%\|" . /NJH') do @if not defined AppVersionDate set "AppVersionDate=[%%G-%%H-%%I %%J:%%K]"

GNU gcc/g++ 稍后会是 运行 -D "APP_VERSION_DATE=%AppVersionDate%" 和 Microsoft C/C++ 编译器 /D "APP_VERSION_DATE=%AppVersionDate%" 作为编译选项之一C/C++ 源代码文件。

还有预定义的宏__DATE____TIME__:

还搜索有关环境变量 SOURCE_DATE_EPOCH 的信息,它可以控制 C/C++ 编译器本身添加到生成的二进制文件的时间戳。