我有点想要为社区做点什么,我正在花时间和我需要帮助。我是.bat和所有的新人。
我有3个文件。
1)包含ID列表的文件 2)具有ID的专有名称列表的文件 3)一个包含大量文本的文件,其中包含随机ID。
我想使用ID和名称来替换第三个文件中的ID。第一个和第二个文件看起来像:
ID.txt
======
001_Blue019
002_Bluer11
003_Buster142
Name.txt
======
Bob Blue
Bluer Baxster
Buster Arnold
一切都完全符合它的正确路线。我想使用这两个文件来更改包含随机放置在文本文件中的ID的第三个文件,某些ID可能会出现多次。我遇到了麻烦,我该如何做到这一点?
第三个文件看起来像这样,但有超过500个不同的ID出现不止一次:
001_Blue019
001_Blue019
001_Blue019
002_Bluer11
001_Blue019
001_Blue019
003_Buster142
最终输出或更改应如下所示
Bob Blue
Bob Blue
Bob Blue
Bluer Baxster
Bob Blue
Bob Blue
Buster Arnold
答案 0 :(得分:0)
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:: remove variables starting $ or #
For %%b IN ($ #) DO FOR /F "delims==" %%a In ('set %%b 2^>Nul') DO SET "%%a="
:: load $*=IDs, #*=names
SET /a count=0
FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" q27679364u.txt') DO SET "$%%a=%%b"
FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" q27679364n.txt') DO SET "#%%a=%%b"&SET /a count+=1
(
FOR /f "delims=" %%a IN (q27679364d.txt) DO (
SET "line=%%a"
CALL :process
)
)>"newfile.txt"
GOTO :EOF
:process
FOR /l %%i IN (1,1,%count%) DO CALL :SUBST "%%$%%i%%" "%%#%%i%%"
ECHO(%line%
GOTO :eof
:SUBST
CALL SET "line=%%line:%~1=%~2%%
GOTO :eof
我使用名为q27679364u.txt
的文件包含您的ID数据,并使用q27679364n.txt
您的名称数据进行测试。
制作newfile.txt
将此输入数据放在文件q27679364d.txt
中:
substitute here: 001_Blue019
nothing to substitute
what about this? 002_Bluer11 and 003_Buster142 and 001_Blue019
--- now your data ----
001_Blue019
001_Blue019
001_Blue019
002_Bluer11
001_Blue019
001_Blue019
003_Buster142
(我在等待时编写了自己的数据文件;然后在最后添加了数据)
结果是:
substitute here: Bob Blue
nothing to substitute
what about this? Bluer Baxster and Buster Arnold and Bob Blue
--- now your data ----
Bob Blue
Bob Blue
Bob Blue
Bluer Baxster
Bob Blue
Bob Blue
Buster Arnold
出现在newfile.txt
附录
批次的速度并不清楚,但可以通过调整例程来完成大量工作,特别是考虑到正在处理的数据的特性。
通过OP数据的质量复制,我将数据文件中的行数扩展到10,000多个,并测量了上述过程。在我的机器上花了176秒(实际时间取决于机器特性和每个文件的大小。)
然后我修改了例程,假设第三个文件中的数据包含来自ID文件的仅行,按随机顺序并且可能重复。
结果:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:: remove variables starting $ or #
For %%b IN ($ #) DO FOR /F "delims==" %%a In ('set %%b 2^>Nul') DO SET "%%a="
:: load $*=IDs, #*=names
SET /a count=0
FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" q27679364u.txt') DO SET "$%%a=%%b"
FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" q27679364n.txt') DO SET "#%%a=%%b"&SET /a count+=1
(
FOR /f "delims=" %%a IN (q27679364d.txt) DO (
FOR /f "tokens=1*delims=$=" %%i IN ('set $') DO IF /i "%%j"=="%%a" ECHO !#%%i!
)
)>"newfile.txt"
GOTO :EOF
在109秒内跑了 - 这是一个有用的节省。
所以我想得更远。使用相同的数据,我开发了这个:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
:: remove variables starting $ or # or _
For %%b IN ($ # _) DO FOR /F "delims==" %%a In ('set %%b 2^>Nul') DO SET "%%a="
:: load $*=IDs, #*=names
SET /a count=0
FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" q27679364u.txt') DO SET "$%%a=%%b"
FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r ".*" q27679364n.txt') DO SET "#%%a=%%b"&SET /a count+=1
FOR /L %%a IN (1,1,%count%) DO SET "_!$%%a!=!#%%a!"&SET "$%%a="&SET "#%%a="
(
FOR /f "delims=" %%a IN (q27679364d.txt) DO (ECHO !_%%a!
)
)>"newfile.txt"
GOTO :EOF
相同的结果文件,它假定ID和名称都是由“漂亮的字符”构成的 - 那些对CMD
的解析器没有意义的那些字符。字母表(大写和小写)和数字以及集[@#$+_-{}:.]
注意这非常明确地排除了空间, Tab 和逗号,而且该批次很少关于案件的区别......
哦 - 运行时间,你问?
呃,0.63秒。
答案 1 :(得分:0)
如果您的第3个文件只包含ID,如示例所示,那么以下批处理脚本应该非常快:
@echo off
setlocal enableDelayedExpansion
:: Load the list of IDs
set "find="
<name.txt ( for /f "usebackq delims=" %%A in ("id.txt") do (
set "name="
set /p "name="
set "_%%A=!name!"
))
for /f "usebackq delims=" %%A in ("test.txt") do echo(!_%%A!
如果第三个文件中的ID与其他文本混合在一起,那么我有一个不同的快速解决方案,只要您拥有不超过四或五百个ID /名称对,它就能正常工作。它使用JREPL.BAT - 一个混合的JScript /批处理脚本,可以在XP以后的任何Windows机器上本机运行。
@echo off
setlocal enableDelayedExpansion
:: Load the list of IDs
set "find="
for /f "usebackq delims=" %%A in ("id.txt") do set "find=!find!|%%A"
set find
:: Load the list of Names
set "repl="
for /f "usebackq delims=" %%A in ("name.txt") do set "repl=!repl!|%%A"
set repl
:: Substitute Names for all IDs within test.txt and write the result to out.txt
call jrepl find repl /l /t "|" /v /f test.txt /o out.txt