1

我有一份工作,我想将它分配给 AHK,让我每隔 5 分钟运行一次。它需要检查一个 txt 文件的内容,比如说 c:\test.txt。该文件可以包含任意数量的行,格式为:

prog 1
prog 2
prog 3
  ...
prog N

在包含其他文本的行之间。

我的目的是在最后一行的 prog 一词之后告诉 AHK 数字,这是列表中最大的数字,因为这些行在此文件中按数字顺序排列。

我的宏伟想法是检查从“prog 1”到“prog N”的行是否存在,其中 N 是 20 以下的数字,使用 cmd 窗口上的一系列查找命令,获取错误级别,当错误级别达到 1,我将我想要的变量设置为循环索引的值减 1,因为它是最后一次成功运行的 find 命令,因此

i=1
loop 20
{
  type c:\users\me\test.txt | find "prog "%i%
  if  %errorlevel% != 0 
  { 
     num := i-1
     ; exit the loop in some way here
  }
  else 
  {
     i := i+1
  }
 } ; end loop

此时,我感兴趣的只是存储在变量 %num% 中的值。我知道这可能不是完成此任务的最优雅的解决方案,但是对于每天在闲置的笔记本电脑上运行几次,我可以承受性能损失。

到目前为止,我一直停留在这个想法的最基本组成部分:find 命令并将它生成的错误级别传递回 AHK

这是我的代码:(此代码仅用于测试 find 命令,我从 AHK 论坛获得)

Run %COMSPEC% /K type c:\users\me\test.txt | find "prog 4", , max
msgbox %ErrorLevel%
return

当这段代码运行时,无论“prog 4”行是否存在,消息框总是显示值“0”。

当我用 RunWait 替换命令 Run 时,errorlevel 会按预期显示,但在这种情况下,我的自动化过程会出现故障:期望手动关闭 cmd 提示符,我假设 Wait 部分的 *feature"的命令 RunWait。

我怎样才能克服这个障碍?我愿意将整个功能加载到 dos 批处理文件并在最后从批处理文件中获取数字输出,但我开始意识到,使用 AHK 编程比 DOS 批处理编程更容易执行和理解。所以,我的偏好是在 AHK 脚本方面。

谢谢

4

3 回答 3

1

如果您想在 AutoHotkey 中完成所有这些操作,我会这样做

FileRead, Content, C:\test.txt
Loop, parse, Content, `n
{
    RegExMatch(A_Loopfield, "(?i)(?<=prog\s)[\d]+", match)
    If (match > lastMatch)
        lastMatch := match
}

msgbox % lastMatch

编辑以始终获得最高价值

于 2013-11-04T22:00:33.717 回答
1

我只会使用 RegEx 来提取最后一项:

FileRead, cont, test.txt
RegExMatch(cont, "s).*prog (\d+)", num)
msgbox, Hightest number: %num1%

在算术/字符串操作方面,AutoHotkey 在大多数情况下应该足够了。为这样的简单事情调用其他应用程序有点矫枉过正,很可能会减慢您的速度。

正则表达式的解释:

  • s)确定句点(.)将匹配每个字符,包括任何换行符(\r和/或\n)。默认情况下,它将在第一个换行符处停止。请参阅正则表达式选项
  • .*是一个可以匹配任何东西的标准模式。它是找到我们字符串中最后一项的关键,因为只要仍然满足模式,它就会尽可能多地消耗。换句话说,它将丢弃所有内容,直到最后一个prog n,这正是我们想要的。请参阅RegEx 参考中的贪婪
  • (\d+)做了两件事:1)它会找到任何整数序列 2)它会创建一个子模式并将数字存储在我们以后可以显式访问它的地方。

输出 var(此处num:)将是一个伪数组,其中包含任何匹配的子模式以及匹配的整个模式。打印%num%将向您显示几乎整个文件,直到最后一个prog n. %num1%将包含第一个子模式,它是最大的n.

于 2013-11-07T07:43:44.417 回答
1

只需让系统为您获取价值。

RunWait,%comspec% /v:on /c "( for /f "tokens=2" `%f in ('findstr /b /r /c:"prog [0-9]+" c:\users\me\test.txt ') do set max=`%f ) & exit /b !max!",,UseErrorLevel
MsgBox %ErrorLevel%
于 2013-11-05T11:17:31.277 回答