查找稍微可变的字符串并将以下行替换为文本文件的内容
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
您需要更改 sourcedir
和 destdir
的设置以适合您的情况。该列表使用适合我的系统的设置。
我使用了一个名为 q57608034.txt
的文件,其中包含您的数据用于我的测试。
我使用了一个名为 q57608034_repl.txt
的文件,其中包含一些用于测试的虚拟替换数据。
生成定义为 %outfile%
的文件
我只处理你的语句 我希望能够(例如)找到字符串 O 8.0,并将下一行的内容替换为文本文件的内容.格式,
遗憾的是,您描述了结果,但没有提供示例。
上面的代码会找到两个目标字符串,然后用一个文件的内容替换下一行。
外层循环使用 find...
的输出作为输入,它在每行前面加上 [括号] 中的行号。文件的任何行都不会匹配 ""
,因为 ""
不会匹配文件中的 任何 行(包括空行)。 /v
反转条件,显示 不 匹配 ""
的行,即 每行 。 /n
然后在每行前面加上 [number]
.
结果 "input" 然后使用 []
作为分隔符并选择要分配给 %%s
和 *
的标记 1
(这意味着该行的其余部分 - 从源文件读取的整个实际行)到 %%t
.
由于 replacenext
被初始化为 nothing(即变为 not defined
),那么 if
的 else
部分语句被执行。这标记了 "%%t" - 文件中的文字字符串并选择前两列(使用默认分隔符 Space , 和 ; 到 %%c
和 %%d
。如果这两个值与指定为变量 col1
和 col2
的值匹配,则 replacenext
设置为一个值。然后 %%t
被 echo
ed,重复从原始文件中读取的行。
读取下一行时,现在可以定义 replacenext
,如果是,则从替换文本文件中复制替换文本,然后清除 replacenext
,因此将再次解释以下行以匹配 col1
和 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
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
请注意,替换集必须按照与数据文件相同的顺序定义...
我正在尝试使用几个免费软件自动执行 运行 计算化学计算中涉及的稍微费力的过程。我已经找到了大部分我需要做的事情的答案,但我错过了最后一块拼图,可能是因为它很不寻常,而且我不知道我选择的语言是否可行 - 批处理文件.我之所以选择这个,部分原因是我过去很难使用 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
您需要更改 sourcedir
和 destdir
的设置以适合您的情况。该列表使用适合我的系统的设置。
我使用了一个名为 q57608034.txt
的文件,其中包含您的数据用于我的测试。
我使用了一个名为 q57608034_repl.txt
的文件,其中包含一些用于测试的虚拟替换数据。
生成定义为 %outfile%
我只处理你的语句 我希望能够(例如)找到字符串 O 8.0,并将下一行的内容替换为文本文件的内容.格式,
遗憾的是,您描述了结果,但没有提供示例。
上面的代码会找到两个目标字符串,然后用一个文件的内容替换下一行。
外层循环使用 find...
的输出作为输入,它在每行前面加上 [括号] 中的行号。文件的任何行都不会匹配 ""
,因为 ""
不会匹配文件中的 任何 行(包括空行)。 /v
反转条件,显示 不 匹配 ""
的行,即 每行 。 /n
然后在每行前面加上 [number]
.
结果 "input" 然后使用 []
作为分隔符并选择要分配给 %%s
和 *
的标记 1
(这意味着该行的其余部分 - 从源文件读取的整个实际行)到 %%t
.
由于 replacenext
被初始化为 nothing(即变为 not defined
),那么 if
的 else
部分语句被执行。这标记了 "%%t" - 文件中的文字字符串并选择前两列(使用默认分隔符 Space , 和 ; 到 %%c
和 %%d
。如果这两个值与指定为变量 col1
和 col2
的值匹配,则 replacenext
设置为一个值。然后 %%t
被 echo
ed,重复从原始文件中读取的行。
读取下一行时,现在可以定义 replacenext
,如果是,则从替换文本文件中复制替换文本,然后清除 replacenext
,因此将再次解释以下行以匹配 col1
和 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
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
请注意,替换集必须按照与数据文件相同的顺序定义...