我找到了许多解决这个问题的办法,但是不幸的是,它们似乎都不适用于我的 Windows 系统。
我正在FOR
批处理文件中运行一个循环来循环遍历多个文本文件。对于每个文本文件,ECHO
如果 (来自 WinGNU) 返回一行,我希望得到它的名称(并可能将输出重定向到文件)grep
。快速的谷歌搜索告诉我这样做:
IF grep -c pattern file ( stuff )
但这会引发错误
-c was unexpected at this time.
grep --quiet
或者,我认为我可以使用如下退出代码:
grep -q pattern file
IF ERRORLEVEL 1 ( stuff )
即使 grep 成功,这也总是会导致 IF 测试失败。
如果我的 grep 找到匹配项,是否有一个好的方法可以在 Windows 中运行条件语句?
我的代码是:
SET locations=( a, long, list, of, last, two, octets )
SETLOCAL ENABLEDELAYEDEXPANSION
FOR %%r IN %locations% DO (
grep -i "^\[CardSwipe\]" \\10.0.%%r\path\to\file.ini
IF ERRORLEVEL 1 echo %%r
我的输出是:
[this line left intentionally blank] :)
答案1
我想不出用 Batch 来做这件事的好方法,尤其是因为你引入了我不熟悉的非本机命令行工具。不过,PowerShell 通常更适合这样的任务。
这应该可以在 PowerShell 中为您完成这项工作:
$Hosts = @('1.1','1.2','101.243','54.28')
$Hosts | ForEach-Object {
if ((Get-Content "\\10.0.$_\path\to\file.ini" | Select-String "^\[CardSwipe\]").length -ne 0) {
Write-Output $_}}
具体细节如下:
- 我们将
$Hosts
其定义为一个数组,其中包含表示要检查的每个系统的最后两个八位字节的字符串。另一种设置方法是使用一个文本文件,每行一个条目。 - 然后我们将数组导入其中
ForEach-Object
,顾名思义,它将对数组中的每个对象执行命令。如果您使用文本文件作为列表,则需要使用 来获取它,Get-Content
然后将其导入ForEach-Object
其中代替变量。 - 条件中的脚本
if
将为您进行搜索。 Get-Content
按照其说明进行操作 - 获取内容。"\\10.0.$_\path\to\file.ini"
是我们给出的目标Get-Content
。通过将字符串括在双引号中,我们告诉 PowerShell 我们希望它在传递参数之前扩展字符串中的变量。$_
是一个内置变量,它引用正在处理的对象,例如ForEach-Object
。- 的输出通过
Get-Content
管道传输到Select-String
。Select-String
对于 PowerShell 来说或多或少是 grep - 事实上,我有点惊讶这个没有内置别名,因为其他 cmdlet(他们称之为 PowerShell 命令)有类似 *nix 命令的别名,如 ls 和 wget。 "^\[CardSwipe\]"
- 哦,是的。Select-String
顺便说一下,采用 RegEx。- 将命令括在括号中允许您直接检索它们生成的对象的属性,而不必先将它们转储到变量或其他东西中。所以,这
( ... ).length
意味着我想要获取括号内脚本输出的任何对象的长度。对于字符串,这是基本字符长度。对于数组,这是数组中成员的数量。当检索文本文件或类似对象时,它将作为“字符串数组”返回。因此,对象的长度属性值将等于文本中的行数。 -ne
是“不等于”的比较运算符。如果Select-String
未找到任何匹配项,则其输出将是一个长度为零的空数组。其他任何内容的长度都将为 1 或更大,因此我们触发if
on-ne 0
。Write-Output
是另一个不言自明的命令。它写入输出。在本例中,我们告诉它我们想要输出当前正在处理的对象ForEach-Object
。当然,由于这是在if
块内,因此只有当 ini 文件符合给定条件时才会发生这种情况。输出将是发生这种情况时正在处理的“最后两个八位字节”。