如何将文本替换为文本文件中的特定行?

时间:2017-04-21 16:22:38

标签: batch-file replace

我每天都会下载这些会计报告,并将其格式化为Quickbooks可以导入的内容。

Quickbooks使用3行标题,第一行数据是唯一的,因为它以字符串“TRNS”开头,所有以下数据行以“SPL”开头。

我非常接近自动执行此操作,但我在编写批处理文件时遇到困难,该文件会将第4行的“SPL”重命名为“TRNS”,而不会替换“SPL”的所有实例“TRNS”。

以下是基于本网站上其他一些帖子的内容。有没有办法让它从第4行开始并只运行一次?

set "search=SPL"
set "replace=TRNS"
set "textfile=Input.txt"
set "newfile=Output.txt"
(for /f "delims=" %%i in (%textfile%) do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    set "line=!line:%search%=%replace%!"
    echo(!line!
    endlocal
))>"%newfile%"

这是目前文件的图像。

The circled text is what needs to be replaced

由于

3 个答案:

答案 0 :(得分:0)

一个简单的行计数器应该有所帮助:

set "search=SPL"
set "replace=TRNS"
set "textfile=Input.txt"
set "newfile=Output.txt"
set lineNr=0
(for /f "delims=" %%i in (%textfile%) do (
    set /a lineNr+=1
    set "line=%%i"
    setlocal enabledelayedexpansion
    if !lineNr!==4 set "line=!line:%search%=%replace%!"
    echo(!line!
    endlocal
))>"%newfile%"

答案 1 :(得分:0)

您可以使用goto循环和input redirection

@echo off
rem // Do all operations in a sub-routine, redirect files once only here:
< "Input.txt" > "Output.txt" call :SUB
exit /B

:SUB
setlocal EnableDelayedExpansion
rem /* The following `goto` loop is executed only until the matching line is found;
rem    everything beyond is handled by a single `findstr` command later: */
:LOOP
rem // Read a single line from the input data:
set "LINE=" & set /P LINE=""
rem /* Terminate sub-routine if an empty line is encountered;
rem    this is needed to not have an infinite loop in case no line matches;
rem    data past that point are lost: */
if not defined LINE goto :EOF
rem /* The following condition is fulfilled if the line begins with `SPL`;
rem    replace `if` by `if /I` to search case-insensitively: */
if "!LINE!"=="SPL!LINE:*SPL=!" (
    rem // Return the modified line, then continue below, leaving the loop:
    echo(TRNS!LINE:*SPL=!
) else (
    rem // Return the original line:
    echo(!LINE!
    rem // Jump to the beginning of the loop:
    goto :LOOP
)
rem /* Return the remaining data; the very last line must be terminated by a
rem    line-break, otherwise `findstr` might hang indefinitely: */
findstr "^"
endlocal
goto :EOF

goto循环很慢,但由于它仅在遇到匹配行时执行,这是第四行,根据您的描述,整体方法比使用for /F更快循环,特别是在后面有很多行的情况下,因为所有这些行都由findstr返回而没有任何解析。但是,最后一行必须以换行符结束;否则,findstr可能会挂起(取决于Windows版本)。

答案 2 :(得分:0)

这是一个纯批处理解决方案,只要前4行是&lt; = 1021个字符长,并以\ r \ n(回车/换行)结束。我相信这是最快的纯批次解决方案。

@echo off
setlocal enableDelayedExpansion
<input.txt >output.txt (
  for /l %%N in (1 1 3) do (
    set "ln="
    set /p "ln="
    echo(!ln!
  )
  set "ln="
  set /p "ln="
  echo TRNS!ln:~3!
  findstr "^"
)

如果你有JREPL.BAT,那么你可以使用:

jrepl "^SPL" "TRNS" /inc 4 /f input.txt /o output.txt

如果要覆盖原始文件,则

jrepl "^SPL" "TRNS" /inc 4 /f input.txt /o -

如果标题行的数量可能会有所不同,并且您只想更改以SPL开头的第一个遇到的行,那么

jrepl "^SPL" "skip=true;$txt=TRNS" /jq /f input.txt /o output.txt

jrepl "^SPL" "TRNS" /exc "/^SPL/+1:-1" /f input.txt /o output.txt