批量在文本文件中插入一行

时间:2017-07-13 08:16:32

标签: batch-file

我的目标是创建一个能够在特定行下插入字符串的脚本。这就是我所做的:

SETLOCAL ENABLEDELAYEDEXPANSION


set outputFile=C:\Utilisateurs\a669884\Documents\script22.txt
set "_strInsert=import java.interceptor.ReportInterceptor;"
set "_strFind=import javax.interceptor.Interceptors;"


:Ask
echo Are you in the good folder (wlp-cas-provider)?(Y/N)
set INPUT=
set /P INPUT=Type input: %=%
If /I "%INPUT%"=="y" goto yes 
If /I "%INPUT%"=="n" goto no
echo Incorrect input & goto Ask

:yes

for %%i in (*.java) DO (
FOR /F "usebackq delims=" %%A IN ("%%i") DO (
  Echo %%A | Find "%_strFind%" && ECHO %%A>>"%outputFile%" && ECHO %_strInsert%>>"%outputFile%"
  IF [!errorlevel!] == [1] ECHO %%A>>"%outputFile%"
)
MOVE /Y "%outputFile%" "%%i" && DEL /F /Q "%outputFile%"
)

:no 
echo Oh no! Go to the right folder and comeback
cls
pause

主要思想是将修改后的文本复制到临时文件中并将其粘贴到原始文件中。之后,临时文件将被删除。

当代码仅在一个文件上完成时,代码工作正常。使用for为了在文件夹中的所有.java文件上执行此操作,它不再起作用了。临时文件script22.txt不再被删除,文本也会堆积在其中。

2 个答案:

答案 0 :(得分:0)

这些方面的内容如何:(未经测试)

@ECHO OFF
FOR %%A IN ("%CD%") DO IF /I NOT "%%~nxA"=="wlp-cas-provider" (
    ECHO=Please change directory to wlp-cas-provider
    ECHO= before running this script again.
    ECHO=
    ECHO=Press any key to exit ...
    PAUSE>NUL
    GOTO :EOF)

SET "_strFind=import javax.interceptor.Interceptors;"
SET "_strInsert=import java.interceptor.ReportInterceptor;"

SETLOCAL ENABLEDELAYEDEXPANSION
SET NL=^


SET "str2Add=%_strFind%!NL!%_strInsert%"

FOR /F "TOKENS=1-2* DELIMS=:" %%A IN ('FINDSTR/BLINC:"%_strFind%" *.java 2^>NUL'
) DO (SET/A "i=1+%%B"
    FINDSTR/BLINC:"%_strInsert%" "%%A"|FINDSTR/B "!i!:">NUL
    IF ERRORLEVEL 1 ((  FOR /F "TOKENS=1* DELIMS=:" %%D IN ('FINDSTR/N $ "%%A"'
            ) DO IF %%D EQU %%B (ECHO=!str2Add!) ELSE ECHO=%%E)>>"%%A.tmp"))

FOR %%A IN (*.java.tmp) DO IF EXIST "%%~nA" (DEL "%%~nA" && REN "%%A" "%%~nA")

答案 1 :(得分:0)

脚本中没有严重的逻辑错误,为什么循环失败。我怀疑它是导致意外行为的管道|,因为它为任一侧启动一个新的命令提示符(cmd)实例,其中左侧接收已经扩展的字符串({{1 }}),其中可能包含对echo %%A具有特殊含义的字符。

以下是您的脚本可能的改进 - 请参阅所有解释性说明(cmd):

rem

这允许字面上所有字符出现在搜索字符串中。请注意,引号@echo off setlocal DisableDelayedExpansion rem // Define constants here: set "targetFolder=C:\Utilisateurs\wlp-cas-provider" set "fileMask=*.java" set "outputFile=C:\Utilisateurs\a669884\Documents\script22.txt" set "_strInsert=import java.interceptor.ReportInterceptor;" set "_strFind=import javax.interceptor.Interceptors;" rem // Enumerate all matching files: for %%I in ("%targetFolder%\%fileMask%") do ( rem /* Redirect the output of the whole `for /F` loop at once; rem this improves the performance, and there is no appending `>>`, rem so it does not matter whether the file already exists before: */ > "%outputFile%" ( rem /* Use `findstr /N` to precede every line by its line number rem and a colon, so no line appears empty to `for /F` any more; rem remember that `for /F` ignores empty lines otherwise: */ for /F "delims=" %%A in ('findstr /N "^" "%%~I"') do ( rem // Store the current line string with line number prefix: set "line=%%A" rem // Toggle delayed expansion to maintain exclamation marks: setlocal EnableDelayedExpansion rem // Remove the line number prefix and the colon: set "line=!line:*:=!" rem // Return the original line unconditionally: echo(!line! rem /* Explicitly initiate another child `cmd` instance on the rem left side of the pipe with delayed expansion enabled; rem escape the delayed expansion like `^^!` not to be rem processed by the parent `cmd` instance, so the child rem `cmd` instance receives the variable `!line!` only; rem therefore strings potentially containing special rem characters are expanded at the very latest point: */ (cmd /V /C echo(^^!line^^!| find "!_strFind!" > nul) && ( rem /* The string to search has been found, so return the rem string to insert after it at this point: */ echo(!_strInsert! ) endlocal ) ) rem // Move the result file over the currently iterated one: move /Y "%outputFile%" "%%~I" > nul ) endlocal exit /B 需要加倍才能由"正确处理。如果希望整行与搜索字符串匹配,请将find命令行替换为find。在这种情况下,如果引号出现在搜索字符串中,请将其转义为findstr /X /C:"!_strFind!";字面反斜杠需要像\"一样加倍。如果您想要不区分大小写搜索,请将\\选项添加到/Ifind

您可以避免包含管道的块......:

findstr

...当您使用 (cmd /V /C echo(^^!line^^!| find "!_strFind!" > nul) && ( echo(!_strInsert! ) 语句来比较字符串时。

例如,如果该行应包含搜索字符串,请使用此字符:

if

由于使用了sub-string replacement方法,因此总是进行不区分大小写的搜索。如果搜索字符串中出现以下任何字符,则此方法可能会失败: if not "!line!"=="!line:*%_strFind%=!" echo(!_strInsert! ^!%=

如果希望整行与搜索字符串匹配,请改用:

"

这是一个区分大小写的搜索,除非您将 if "!line!"=="!_strFind!" echo(!_strInsert! 开关添加到/I语句。