gpt4 book ai didi

batch-file - 从文本文件中随机选择一行并将该行设置为变量

转载 作者:行者123 更新时间:2023-12-03 23:05:22 25 4
gpt4 key购买 nike

如何从文本文件中随机选择线路/ip,并将其设置为变量。

我的意思是:

set IP=TheLine/IPFromOfTheFile

最佳答案

基于数组的解决方案似乎应该是最快的,因为它们只读取文件一次。但是当环境变得非常大时,变量操作就会变得非常慢。因此,基于阵列的解决方案提供了非线性性能。如果文件很大,它们可能会非常慢。

对于一个纯粹的基于批处理的解决方案,无论文件大小如何,都能提供良好的线性性能,我喜欢 aschipfl's answer 。但是,由于/f EOL 值的默认值,以 ; 开头的行存在问题。如果文件为空,它也会失败。这是一个近乎完美的修正版本。

@echo off
setlocal
set "file=test.txt"
set "LINE="
for /F %%N in (
'type "%file%" ^| find /C /V ""'
) do set set /A RND=%RANDOM% %% %%N 2>nul || goto :BREAK
if %RND%>0 (set "skip=skip^=%RND%") else set "skip="
for /F usebackq^ %skip%^ delims^=^ eol^= %%L in ("%file%") do (
set "LINE=%%L"
goto :BREAK
)
:BREAK
set LINE

上面还有一个缺陷 - 如果所选行为空,那么由于 FOR/F 的设计,它将返回下一个非空行。

解决这个问题的“标准”方法是使用 FINDSTR 为每行添加行号前缀,然后使用扩展查找/替换来删除前缀。鉴于行号前缀的存在,我喜欢使用额外的 FINDSTR 来选择正确的行,而不是依赖于 FOR/F

@echo off
setlocal
set "file=test.txt"
set "ln="
for /f %%N in (
'type "%file%" ^| find /c /v ""'
) do set /a rnd=%random% %% %%N + 1 2>nul || goto :result
for /f "delims=" %%L in (
'findstr /n "^" "%file%" ^| findstr "^%rnd%:"'
) do set "ln=%%L"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
:result
set ln

如果您知道所有行的长度都 <= 1021 字节,那么有一个更简单的解决方案来处理空行,即使用 SET/P 而不是 FOR/F 读取文件。

@echo off
setlocal
set "file=\utils\jrepl.bat"
set "ln="
for /f %%N in (
'type "%file%" ^| find /c /v ""'
) do set /a rnd=%random% %% %%N 2>nul || goto :result
<"%file%" (
for /l %%N in (1 1 %rnd%) do set /p "ln="
set "ln="
set /p "ln="
)
:result
set ln

只是为了恶心,我决定根据我的 JREPL.BAT regular expression text processing utility 编写一个解决方案。可以编写优化的混合 JScript/批处理脚本,但如果您已经拥有 JREPL,那么 JREPL 会很方便。

如果您只需要打印随机一行,那么它就是一个简单的单行:

call jrepl "^.*" $0 /c /jmatch /jbeg "rnd=Math.floor(Math.random()*cnt)+1" /jbegln "skip=(rnd!=ln)" /f test.txt

需要更多代码来获取变量中的值:

@echo off
setlocal
set "ln="
for /f "delims=" %%L in (
'jrepl "^.*" $0 /c /n 1 /jmatch /jbeg "rnd=Math.floor(Math.random()*cnt)+1" /jbegln "skip=(rnd!=ln)" /f test.txt'
) do set "ln=%%L"
setlocal enableDelayedExpansion
set "ln=!ln:*:=!"
:result
set ln

如果行全部 <= 1021 并且您不介意临时文件,那么您可以使用 SET/P

@echo off
setlocal
call jrepl "^.*" $0 /c /jmatch /jbeg "rnd=Math.floor(Math.random()*cnt)+1" /jbegln "skip=(rnd!=ln)" /f test.txt /o temp.txt
set "ln="
<temp.txt set /p "ln="
del temp.txt
:result
set ln

关于batch-file - 从文本文件中随机选择一行并将该行设置为变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34828574/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com