查找稍微可变的字符串并将以下行替换为文本文件的内容

Find slightly variable string and replace following line with contents of a text file

我正在尝试使用几个免费软件自动执行 运行 计算化学计算中涉及的稍微费力的过程。我已经找到了大部分我需要做的事情的答案,但我错过了最后一块拼图,可能是因为它很不寻常,而且我不知道我选择的语言是否可行 - 批处理文件.我之所以选择这个,部分原因是我过去很难使用 C++ 或 JavaScript 来读取或编辑其他文件,而 Batch(朋友推荐的)第一次做到这一点没有任何困难。

我在下面复制了我的输入文件的代表性示例。

Text above

 $DATA  
Adenosine                                                                
C1     0
O           8.0      0.1319600000      7.8748100000      0.9316500000
    DZV     0

C           6.0     -0.5337400000      7.9322600000      2.1608300000
   DZV     0

N           7.0      1.4158500000      4.2659800000      1.3661200000
   DZV     0

H           1.0     -0.4456400000      8.9556600000      2.5897400000
   DZV     0

More coordinates below

我希望能够(例如)找到字符串 O 8.0,并将下一行的内容替换为文本文件的内容。格式,

Atom           atomic charge            coordinates
   text
blank space

需要保留 - 空白 space 是必不可少的。

这里是最终产品的一个例子(氧气和碳;为简洁起见省略了氮气和氢气):

 $DATA  
Adenosine                                                                       
C1       0
O           8.0      0.1319600000      7.8748100000      0.9316500000
S   5
1      2266.1767785             -0.53431809926E-02
2       340.87010191            -0.39890039230E-01
3        77.363135167           -0.17853911985
4        21.479644940           -0.46427684959
5         6.6589433124          -0.44309745172
S   1
1         0.80975975668          1.0000000
S   1
1         0.25530772234          1.0000000
P   3
1        17.721504317            0.43394573193E-01
2         3.8635505440           0.23094120765
3         1.0480920883           0.51375311064
P   1
1         0.27641544411          1.0000000
D   1
1         1.2000000              1.0000000

C           6.0     -0.5337400000      7.9322600000      2.1608300000
S   5
1      1238.4016938              0.54568832082E-02
2       186.29004992             0.40638409211E-01
3        42.251176346            0.18025593888
4        11.676557932            0.46315121755
5         3.5930506482           0.44087173314
S   1
1         0.40245147363          1.0000000
S   1
1         0.13090182668          1.0000000
P   3
1         9.4680970621           0.38387871728E-01
2         2.0103545142           0.21117025112
3         0.54771004707          0.51328172114
P   1
1         0.15268613795          1.0000000
D   1
1         0.8000000              1.0000000

我已经使用以下代码成功查找和替换字符串:

set "search=SearchItem"
set "replace=Replacement"
set "textfile=text.txt"
set "newfile=newfile.txt"
(for /f "delims=" %%i in (%textfile%) do (
    set "line=%%i"
    setlocal enabledelayedexpansion
    set "line=!line:%search%=%replace%!"
    echo(!line!
    endlocal
))>"%newfile%"
del %textfile%
rename %newfile%  %textfile%

我在这里找到了 "Find a line in a file and replace the next line" 类型的代码: 但这不太奏效——代码似乎变成了:

Atom           atomic charge            coordinates
   text
blank space

进入:

blank space
replacement text
blank space

而且它只对一个原子执行此操作。

@ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q57608034.txt"
SET "filename2=%sourcedir%\q57608034_repl.txt"
SET "outfile=%destdir%\outfile.txt"

SET "col1=O"
SET "col2=8.0"

SET "replacenext="

(
FOR /f "tokens=1*delims=[]" %%s IN ('find /n /v "" "%filename1%"') DO (
 IF DEFINED replacenext (SET "replacenext="&TYPE "%filename2%
 ) ELSE (
  FOR /f "tokens=1,2" %%c IN ("%%t") DO IF "%%c"=="%col1%" IF "%%d"=="%col2%" SET "replacenext=Y"
  ECHO(%%t
 )
)
)>"%outfile%"

GOTO :EOF

您需要更改 sourcedirdestdir 的设置以适合您的情况。该列表使用适合我的系统的设置。

我使用了一个名为 q57608034.txt 的文件,其中包含您的数据用于我的测试。

我使用了一个名为 q57608034_repl.txt 的文件,其中包含一些用于测试的虚拟替换数据。

生成定义为 %outfile%

的文件

我只处理你的语句 我希望能够(例如)找到字符串 O 8.0,并将下一行的内容替换为文本文件的内容.格式,

遗憾的是,您描述了结果,但没有提供示例。

上面的代码会找到两个目标字符串,然后用一个文件的内容替换下一行。

外层循环使用 find... 的输出作为输入,它在每行前面加上 [括号] 中的行号。文件的任何行都不会匹配 "",因为 "" 不会匹配文件中的 任何 行(包括空行)。 /v 反转条件,显示 匹配 "" 的行,即 每行 /n 然后在每行前面加上 [number].

结果 "input" 然后使用 [] 作为分隔符并选择要分配给 %%s* 的标记 1 (这意味着该行的其余部分 - 从源文件读取的整个实际行)到 %%t.

由于 replacenext 被初始化为 nothing(即变为 not defined),那么 ifelse 部分语句被执行。这标记了 "%%t" - 文件中的文字字符串并选择前两列(使用默认分隔符 Space ,;%%c%%d。如果这两个值与指定为变量 col1col2 的值匹配,则 replacenext 设置为一个值。然后 %%techoed,重复从原始文件中读取的行。

读取下一行时,现在可以定义 replacenext,如果是,则从替换文本文件中复制替换文本,然后清除 replacenext,因此将再次解释以下行以匹配 col1col2.

其结果是:

Text above

$DATA
Adenosine
C1     0
O           8.0      0.1319600000      7.8748100000      0.9316500000
Replacement Text

C           6.0     -0.5337400000      7.9322600000      2.1608300000
DZV     0

N           7.0      1.4158500000      4.2659800000      1.3661200000
DZV     0

H           1.0     -0.4456400000      8.9556600000      2.5897400000
DZV     0

More coordinates below

Magoo的好答案使用了常用的查找技术和
避免延迟扩展的标志变量。

要检测触发行,您还可以使用其 RegEx 功能回显 findstr 或
只需准确比较行的开头:

:: Q:\Test19\SO_57608034.cmd
@Echo off
set "search=O           8"
set "textfile=text.txt"
set "newfile=newfile.txt"
set "insertfile=other.txt"
Set "SkipNextLine="

(for /f "tokens=1,* delims=]" %%h in ('find /N /V "" "%textfile%") do (
    if defined SkipNextLine (
       type "%insertfile%"
       Set "SkipNextLine="
    ) else (
        Echo:%%i|findstr /BC:"%search%" >NUL 2>&1 && Set SkipNextLine=yes
        Echo:%%i
    )
))>"%newfile%"
del "%textfile%"
rename "%newfile%"  "%textfile%"

你的问题很不完整:

  • 您要执行几次替换吗?如果是这样,
  • 您如何指定所需的替换?
  • 为什么需要替换为文本文件?字符串不够吗?

我用自己的想法解决了你遗漏的需求:

@echo off
setlocal EnableDelayedExpansion

rem Define the replacement set
set i=0
for %%a in (
      "O           8.0= Replace   X"
      "N           7.0=   Other   Y"
      "EndOfSet" ) do (
   set /A i+=1
   set "replace[!i!]=%%~a"
)

rem Initialize the replacement set
set /A i=1, repLen=15, repThis=0
set "search=%replace[1]%"

rem Process the file
(for /f "tokens=1* delims=:" %%a in ('findstr /N "^" test.txt') do (
   if !repThis! equ 1 (
      for /F "tokens=2 delims==" %%x in ("!search!") do echo %%x
      set /A i+=1, repThis=0
      for %%i in (!i!) do set "search=!replace[%%i]!"
   ) else (
      echo/%%b
      set "line=%%b"
      if "!line:~0,%repLen%!" == "!search:~0,%repLen%!" set "repThis=1"
   )
)) > newFile.txt

输出:

上面的文字

 $DATA  
Adenosine                                                                
C1     0
O           8.0      0.1319600000      7.8748100000      0.9316500000
 Replace   X

C           6.0     -0.5337400000      7.9322600000      2.1608300000
   DZV     0

N           7.0      1.4158500000      4.2659800000      1.3661200000
   Other   Y

H           1.0     -0.4456400000      8.9556600000      2.5897400000
   DZV     0

More coordinates below

请注意,替换集必须按照与数据文件相同的顺序定义...