大家晚上好
我对批处理文件一无所知,但是我需要它来做一些事情。
让我解释一下:我要做的是打开file.c并浏览此行代码
#define var ((uint32_t) 1000)
我想要的是通过用户先前输入的值来更改值1000
,不同的是,每次用户输入值{{1}时,该值并不总是1000。 },
我希望将其替换为我的.c文件,然后需要替换250000个
250000
一次又一次地使用另一个变量,所以我希望我的程序替换定义var((uint32_t)之后的内容,并替换为用户输入的内容,希望您对我想做什么有所了解。 / p>
我添加了我的程序,但是它并没有真正起作用,请问您有什么想法吗?
#define var ((uint32_t) 250000)
答案 0 :(得分:2)
用批处理脚本修改文本文件并不是一件容易的事,特别是当它的格式很容易被破坏时,即使仅添加或更改一个字符,例如(C)源代码。
尽管如此,我仍然不得不尝试使用纯批处理脚本来管理它-请参阅代码中的解释性说明。
主要挑战是:
#define var ((uint32_t) 1000)
的行,该字符串可能在几乎任何位置都包含多个空格( SPACE 和 TAB ),当然,除了关键字和数字之外uint32_t
相对于数字的位置; 所以这里是
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=C:\Users\astre\Desktop\test\fichier.c" & rem // (path or name of input file)
set "_TEMP=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (path or name of temporary file)
rem // Gather TAB character:
for /F "delims=" %%T in ('forfiles /P "%~dp0." /M "%~nx0" /C "cmd /C echo/0x09"') do set "_T=%%T"
rem // Build white-space classes for search expressions:
set "_S=[ %_T%]" & set "_S0=[ %_T%]*" & set "_S1=[ %_T%][ %_T%]*"
rem // Build digit classes for search expressions:
set "_D=[0123456789]" & set "_D0=[0123456789]*" & set "_D1=[0123456789][0123456789]*"
rem // Define expression (word) before number to replace:
set "_SPLIT=uint32_t"
rem // Build search expression for `findstr`:
set "_SEARCH=^%_S0%#define%_S1%var%_S1%(%_S0%(%_S0%%_SPLIT%%_S0%)%_S1%%_D1%%_S0%)%_S0%$"
rem // Write output to temporary file:
> "%_TEMP%" (
set "FLAG="
rem /* Read input file line by line, prefixed by current line number,
rem so lines appear non-empty to `for /F`, which would be ignored: */
for /F "delims=" %%L in ('findstr /N "^" "%_FILE%"') do (
set "LINE=%%L"
setlocal EnableDelayedExpansion
set "LINE=!LINE:*:=!"
rem // Check whether current line (without line number prefix) matches search expression:
cmd /V /C echo(^^!LINE^^!| > nul findstr /R /I /C:"!_SEARCH!" && (
rem /* Current line matches, so split it into two parts at certain expression (word);
rem the second part is the one that holds the number to replace later: */
set "AFTER=!LINE:*%_SPLIT%=!"
set "BEFORE=!LINE!|" & for /F "delims=" %%K in ("%_SPLIT%!AFTER!|") do set "BEFORE=!BEFORE:%%K=!"
rem /* Toggle delayed expansion to avoid troubles with exclamation marks `!`;
rem this requires `setlocal`/`endlocal` pairs, which localise environments;
rem hence use `for /F` to transport some values over `endlocal` barrier;
rem the temporary underscores `_` ensure none of the tokens appear empty: */
for /F "tokens=1* delims=| eol=|" %%G in ("_!BEFORE!|!AFTER!_") do (
rem // Split the second part at number:
for /F "tokens=1* delims=0123456789 eol=0" %%I in ("_!AFTER!_") do (
endlocal
set "FLAG=#"
set "BEFORE=%%G" & set "AFTER=%%H"
set "LEFT=%%I" & set "RIGHT=%%J"
setlocal EnableDelayedExpansion
rem // Append the part before the number to the first part:
set "BEFORE=!BEFORE:~1!%_SPLIT%!LEFT:~1!"
rem // Extract the number from the second part:
set "NUMBER=_!AFTER!|" & set "NUMBER=!NUMBER:*%%I=!" & set "NUMBER=!NUMBER:%%J|=!"
rem // Store the part after the number as the new second part:
set "AFTER=!RIGHT:~,-1!"
)
)
rem // Prompt user for new number (keep old one as per default):
set "ENTRY=!NUMBER!" & > con set /P ENTRY="Number (!ENTRY!): " && (
rem // Verify that entry is purely numeric (with white-spaces ignored):
set "ENTRY=!ENTRY: =!" & set "ENTRY=!ENTRY:%_T%=!"
(for /F "delims=0123456789 eol=0" %%K in ("!ENTRY!") do rem/) && >&2 (
echo Number entry is not purely numeric; keeping former value !NUMBER!.
) || set "NUMBER=!ENTRY!"
)
rem // Return line with the number exchanged:
echo(!BEFORE!!NUMBER!!AFTER!
) || (
rem // Current line does not match search expression, so return it unedited:
echo(!LINE:*:=!
)
endlocal
)
)
rem // Move temporary file onto input file, but only if a search expression has been found:
if defined FLAG (
> nul move /Y "%_TEMP%" "%_FILE%"
) else del "%_TEMP%"
endlocal
exit /B
Windows命令提示符cmd
有一些限制:
437
,850
,1252
,65001
一些广泛的转换;请参见chcp
command)以找到合适的转换结果; 0x7F
以上代码的字符可能会转换为其他代码,具体取决于代码页;如果您可以接受,则可以再次更改代码页; 0x0D
),后跟换行符(LF,代码{{1}) }),简而言之:CR + LF;带有Unix风格的换行符(LF)的文件可能被正确读取,但是输出文件将包含DOS / Windows风格的换行符;具有MAC样式换行符(CR)的文件无法处理;