我对编写 powershell 脚本完全陌生。到目前为止,我使用普通批次来达到我的目的,因为这是我公司的要求。在此批处理中,我使用嵌套的 foo 循环来比较两个 .txt 文件,具体来说,我想要执行以下操作:
- 文件 1 包含大量字符串。每个字符串都位于一个单独的行中,前面有数字和分号,如下所示:
658;RMS
- 文件 2 是一些长文本。
目的是计算文件 1 中每个字符串在文件 2 中出现的次数,例如RMS 被计数 300 次。
由于我之前的代码在运行时方面存在一些巨大的缺陷(文件 1 大约有 400 行,文件 2 500.000 行),我了解到 Powershell 中的 Select-String 效率更高。
然而,当我正在阅读一些教程时,我不清楚如何继续这里,除了我必须在 .bat 中运行 powershellcode 之外。
我最大的问题是我不确定如何以及在哪里放置我的“变量”,所以两个输入文件 1 和 2
到目前为止,我正在测试这样的 Select-String 方法:
powershell -command "& {Select-String -Path *.txt -Pattern "RMS"}"
我的假设是利用管道,所以像这样:
powershell -command "& {<<path to file one, should read line by line>> | Select-String -Path File2.txt -Pattern "value of file 1"}"
但是,我没有让这个工作。 Powershell 期待某种psobject
在第一根管道之前?
为了获得最佳性能,我会像这样处理这个任务。
- 读取包含条款的 CSV 文件(它is一个 CSV,带有
;
分隔符)
- 将另一个文件读入字符串
- 对于每个术语,计算它在目标字符串中出现的频率(使用
.IndexOf()
)
例如
$data = Import-Csv "file1.txt" -Delimiter ";" -Header ID,Term
$target = Get-Content "file2.txt" -Raw
$counts = @{}
foreach ($term in $data.Term) {
$index = -1
$count = 0
do {
$index = $target.IndexOf($term, $index + 1)
if ($index -gt -1) { $count++ } else { break; }
} while ($true);
$counts[$term] = $count
}
$counts
Notes
-
Import-Csv
将自动使用输入文件中的第一行作为标题。如果您的文件已经有标题,您可以删除-Headers
范围。
-
Get-Content
默认情况下,将把输入文件读取到行数组中。但对于这种方法,将整个文件作为一个大字符串是正确的 - 这就是-Raw
does.
-
@{}
创建一个空的哈希表
-
$data.Term
将访问 CSV 的一列
-
.IndexOf()
区分大小写。默认情况下,PowerShell 不区分大小写,但像这样的本机 .NET 方法不会改变其行为。这可能是也可能不是您需要的 - 使用.ToLower()
on the $target
和$term
如果你不关心情况。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)