批处理文件 - 将行插入文件

时间:2014-12-18 16:44:59

标签: windows batch-file cmd

我正在尝试使用以下代码(来自Write batch variable into specific line in a text file

将一行插入文件
@echo off
setlocal enableextensions enabledelayedexpansion

set inputfile=variables.txt

set tempfile=%random%-%random%.tmp

copy /y nul %tempfile%

set line=0

for /f "delims=" %%l in (%inputfile%) do (
   set /a line+=1
   if !line!==4 (
       echo WORDS YOU REPLACE IT WITH>>%tempfile%
   ) else (
    echo %%l>>%tempfile%
)
)

del %inputfile%
ren %tempfile% %inputfile%

endlocal

我的问题是该文件有注释行(以分号开头)需要保存

; directory during network startup. This statement must indicate a local disc
; drive on your PC and not a network disc drive.
LOCALDRIVE=C:\TEMP;

; PANELISATION PART/NET NAMING CONVENTION
; When jobs are panelised, parts/nets are renamed for each panel step by

当我运行批处理文件时,它会忽略分号行,所以我只得到:

LOCALDRIVE=C:\TEMP;

我需要做什么才能保留分号线?

3 个答案:

答案 0 :(得分:1)

默认情况下,FOR命令会将;视为行尾字符,因此所有以;开头的行都会被忽略。

eol=添加到FOR命令中,如下所示:

for /f "eol= delims=" %%l in (%inputfile%) do (

答案 1 :(得分:1)

EOL选项确定要忽略的行。默认值为分号。如果你知道一个字符永远不会出现在一行的第一个位置,那么你可以简单地将EOL设置为该字符。例如,如果您知道某行不能以|开头,那么您可以使用

for /f "eol=| delims=" %%l in (%inputfile%) do ...

有一种笨拙的语法可以完全禁用EOL,并且还会禁用DELIMS:

for /f delims^=^ eol^= %%l in (%inputfil%) do ...

请注意,FOR / F总是丢弃空行,因此上述任何一个都会导致:

; directory during network startup. This statement must indicate a local disc
; drive on your PC and not a network disc drive.
LOCALDRIVE=C:\TEMP;
; PANELISATION PART/NET NAMING CONVENTION
; When jobs are panelised, parts/nets are renamed for each panel step by

如果要保留空行,则使用技巧。使用FIND或FINDSTR在每行之前插入行号,然后使用扩展查找/替换来删除行号。现在您知道该行永远不会以;开头,因此您可以忽略EOL选项。

for /f "delims=" %%L in ('findstr /n "^" "%inputfile%"') do (
  set "ln=%%L"
  set "ln=!ln:*:=!"
  REM You now have the original line, do whatever needs to be done here
)

但是上述所有问题都有可能导致扩展FOR变量时启用延迟扩展,这意味着包含!的任何内容都将被破坏。要解决此问题,您必须在循环内打开和关闭延迟扩展:

setlocal disableDelayedExpansion
...
for /f "delims=" %%L in (findstr /n "^" "%inputfile%") do (
  set "ln=%%L"
  setlocal enableDelayedExpansion
  set "ln=!ln:*:=!"
  REM You now have the original line with ! preserved, do whatever needs done here
  endlocal
)

此外,当ECHOing一个空行时,它将打印出ECHO is off,除非您执行类似

的操作
echo(!ln!

每次在循环中使用>>时,打开并将写入光标定位到末尾需要花费时间。将整个操作包含在一组括号中并重定向一次会更快。此外,您可以使用单个MOVE命令替换DEL和REN。

这是一个最终的强大脚本:

@echo off
setlocal disableDelayedExpansion
set "inputfile=variables.txt"
set line=0
>"%inputfile%.new" (
  for /f "delims=" %%L in (findstr /n "^" "%inputfile%") do (
    set "txt=%%L"
    set /a line+=1
    setlocal enableDelayedExpansion
    set "txt=!txt:*:=!"
    if !line! equ 4 (
      echo New line content here
    ) else (
      echo(!txt!
    )
    endlocal
  )
)
move /y "%inputfile%.new" "%inputfile%" >nul
endlocal

对于这么简单的任务来说,这是一项非常繁重的工作,它需要大量的奥术知识。

只要

,就会有更快的黑客攻击
  • 您的前4行不超过1021字节
  • 前三行中没有一行包含需要保留的尾随控制字符
  • 其余行没有必须保留的<tab>个字符(MORE会将<tab>转换为空格字符串。
@echo off
setlocal enableDelayedExpansion
set "inputfile=variables.txt"
>"%inputfile%.new" (
  <"%inputfile%" (
    for /l %%N in (1 1 3) do (
      set "ln="
      set /p "ln="
      echo(!ln!
    )
  )
  echo New line content here
  more +4 "%inputfile%"
)
move /y "%inputfile%.new" "%inputfile%"

这仍然是很多工作和神秘的知识。

我会使用我的JREPL.BAT实用程序

Batch对于文本处理来说真的是一个糟糕的工具。这就是我开发JREPL.BAT来使用正则表达式操作文本的原因。它是一个混合的JScript /批处理脚本,可以在XP以后的任何Windows机器上本机运行。它功能多样,功能强大,速度快。

使用JREPL解决您的问题需要最少量的代码。您的问题实际上并不需要正则表达式功能。

jrepl "^" "" /jendln "if (ln==4) $txt='New content here'" /f "variables.txt" /o -

如果在批处理脚本中使用,则必须使用call jrepl ...,因为JREPL.BAT也是批处理脚本。

答案 2 :(得分:0)

看起来你只回显了行分隔符,而不是整行:

echo %% l&gt;&gt;%tempfile%

我在ms-dos脚本上生锈了,所以我不能给你更多。