Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Powershell文本搜索-多个匹配项_Powershell - Fatal编程技术网

Powershell文本搜索-多个匹配项

Powershell文本搜索-多个匹配项,powershell,Powershell,我有一组.txt文件,其中包含以下一个或两个字符串 “红色”、“蓝色”、“绿色”、“橙色”、“紫色”等等列表中还有更多(50+)种可能性 如果有帮助,我可以判断.txt文件是否包含一个或两个项目,但不知道它们是哪一个。字符串模式总是在它们自己的行上 我希望脚本具体告诉我它找到了哪一个或两个字符串匹配(来自主列表),以及找到它们的顺序。(哪一个是第一个) 因为我有很多文本文件要搜索,所以我希望在搜索时将输出结果写入CSV文件 FILENAME1,first_match,second_match

我有一组.txt文件,其中包含以下一个或两个字符串

“红色”、“蓝色”、“绿色”、“橙色”、“紫色”等等
列表中还有更多(50+)种可能性

如果有帮助,我可以判断.txt文件是否包含一个或两个项目,但不知道它们是哪一个。字符串模式总是在它们自己的行上

我希望脚本具体告诉我它找到了哪一个或两个字符串匹配(来自主列表),以及找到它们的顺序。(哪一个是第一个)

因为我有很多文本文件要搜索,所以我希望在搜索时将输出结果写入CSV文件

FILENAME1,first_match,second_match

file1.txt,blue,red
file2.txt,red, blue
file3.txt,orange,
file4.txt,purple,red
file5.txt,purple,
...
我曾尝试使用许多单独的
Select Strings
返回布尔结果来设置变量和找到的任何匹配项,但随着可能的字符串数量的增加,它很快变得丑陋。我对这个问题的搜索结果没有给我提供任何新的想法来尝试。(我肯定我问的方式不对)

我需要循环浏览每个文件中的每一行文本吗

通过检查每个搜索字符串是否存在,我是否陷入了消除方法的过程


我正在寻找一种更优雅的方法来解决这个问题。(如果存在)

您可以使用regex搜索以获取索引(startpos.in line)并结合
选择字符串,该字符串返回行号,您就可以开始了

Select String
支持将数组作为
-Pattern
的值,但不幸的是,即使在使用
-AllMatches
(错误?)时,它也会在第一次匹配后的一行上停止。因此,我们必须对每个单词/模式搜索一次。尝试:

#List of words. Had to escape them because Select-String doesn't return Matches-objects (with Index/location) for SimpleMatch
$words = "purple","blue","red" | ForEach-Object { [regex]::Escape($_) }
#Can also use a list with word/sentence per line using $words = Get-Content patterns.txt | % { [regex]::Escape($_.Trim()) }

#Get all files to search
Get-ChildItem -Filter "test.txt" -Recurse | Foreach-Object { 
    #Has to loop words because Select-String -Pattern "blue","red" won't return match for both pattern. It stops on a line after first match
    foreach ($word in $words) {
        $_ | Select-String -Pattern $word |
        #Select the properties we care about
        Select-Object Path, Line, Pattern, LineNumber, @{n="Index";e={$_.Matches[0].Index}}
    }
} |
#Sort by File (to keep file-matches together), then LineNumber and Index to get the order of matches
Sort-Object Path, LineNumber, Index |
Export-Csv -NoTypeInformation -Path Results.csv -Encoding UTF8
Results.csv

"Path","Line","Pattern","LineNumber","Index"
"C:\Users\frode\Downloads\test.txt","file1.txt,blue,red","blue","3","10"
"C:\Users\frode\Downloads\test.txt","file1.txt,blue,red","red","3","15"
"C:\Users\frode\Downloads\test.txt","file2.txt,red, blue","red","4","10"
"C:\Users\frode\Downloads\test.txt","file2.txt,red, blue","blue","4","15"
"C:\Users\frode\Downloads\test.txt","file4.txt,purple,red","purple","6","10"
"C:\Users\frode\Downloads\test.txt","file4.txt,purple,red","red","6","17"
"C:\Users\frode\Downloads\test.txt","file5.txt,purple,","purple","7","10"

不是很直观但很优雅

下面的switch语句 返回 哪里
  • file1
    首先包含
    蓝色
    ,然后包含
    红色
  • file2
    首先包含
    red
    ,然后包含
    blue

是的,优雅。这正是我所希望的。由于我的列表很长,有没有从文本文件加载$regex的方法?类似于
“($((gc$env:temp\test.txt)-join'|')”“
可能会帮助您开始
$regex = "(purple|blue|red)"

Get-ChildItem $env:TEMP\test\*.txt | Foreach-Object{
    $result = $_.FullName
    switch -Regex -File $_
    {
        $regex {$result = "$($result),$($matches[1])"}
    }
    $result
}
C:\Users\Lieven Keersmaekers\AppData\Local\Temp\test\file1.txt,blue,red
C:\Users\Lieven Keersmaekers\AppData\Local\Temp\test\file2.txt,red,blue