1

我正在尝试自动化一个稍微费力的过程,该过程涉及使用几个免费软件运行计算化学计算。我已经设法找到了我需要做的大部分事情的答案,但我错过了最后一块拼图,可能是因为它很不寻常,而且我不知道我选择的语言是否可能 - 批处理文件. 我之所以选择这个,部分原因是我过去很难让 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

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

Atom           atomic charge            coordinates
   text
blank 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%

我在这里找到了“在文件中查找一行并替换下一行”类型代码:在文件中查找一行并替换下一行 但这并不完全有效 - 代码似乎转向:

Atom           atomic charge            coordinates
   text
blank space

进入:

blank space
replacement text
blank space

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

4

3 回答 3

2
@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...每行前面加上 [brackets] 中的行号。文件的任何行都不会匹配,""因为""不会匹配文件中的任何行(包括空行)。/v反转条件,显示匹配的行"",即每一行。然后在/n每一行前面加上[number].

然后使用[]as 分隔符将生成的“输入”标记化,并选择1要分配给的标记%%s*(这意味着该行的其余部分 - 从源文件读取的整个实际行)到%%t.

由于replacenext被初始化为(即变为not defined) ,因此执行该语句的else一部分。if这将标记 "%%t" - 文件中的文字字符串并选择前两列(使用默认分隔符Space ,;into%%c%%d。如果这两个值与指定为变量的值匹配col1col2然后replacenext设置为一个值。%%t然后echoed,反刍从原始文件中读取的行。

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

结果是:

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
于 2019-08-22T12:07:07.320 回答
0

Magoo的好答案使用通常的技术与 find 进行编号和
避免延迟扩展的标志变量。

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

:: Q:\Test\2019\08\22\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%"
于 2019-08-22T12:26:31.137 回答
0

你的问题很不完整:

  • 是否要执行多个替换?如果是这样的话,
  • 您如何指定所需的替换?
  • 为什么需要用文本文件替换?一个字符串还不够吗?

我用自己的想法来解决您缺少的要求:

@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

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

于 2019-08-22T15:31:57.843 回答