首页 > 解决方案 > 如何在 Powershell 中比较两个 .txt 文件字符串

问题描述

我有 2 个 .txt 文件。txt 文件 A 有:| 狗 | | 大猫 | | 鱼 | | 猴子 | 和txt文件B有:

| 猴子 | | 大猫 | | 松鼠 |

我很难编写一个 Powershell 脚本来接收这两个 .txt 文件及其内容,并在条件语句中比较它们,如果文件 B 具有与 txt 文件相同的任何行字符串的任何内容A,然后它会输出一些东西来表明有一个匹配。

这是我的第一个编程问题,所以我尽力解释我的情况

标签: powershellfor-loopconditional-statementspowershell-4.0txt

解决方案


希望经过一番尝试后,可能会出现这样的结果?

$fileA = (Get-Content C:\temp\FileA.txt).Trim()
$fileB = (Get-Content C:\temp\FileB.txt).Trim()

Compare-Object $fileA $fileB -ExcludeDifferent -IncludeEqual  | Tee-Object -Variable compareObject
$compareObject | ForEach-Object -Begin { "`n" } -Process { "Found $($_.InputObject) in both files!" }

输出

InputObject SideIndicator
----------- -------------
Big Cat     ==
Monkey      ==


Found Big Cat in both files!
Found Monkey in both files!

解释

假设管道实际上不是文件的一部分,并且它们分开到自己的行中

$fileA = @"
 Dog
Big Cat
Fish
Monkey
"@

$fileB = @"
Big Cat
Squirrel 
Monkey
"@

以下几行获取每个文件的内容并将它们放入字符串数组中。然后该.Trim()方法从数组中每个项目的开头和结尾删除任何空格

$fileA = (Get-Content C:\temp\FileA.txt).Trim()
$fileB = (Get-Content C:\temp\FileB.txt).Trim()

接下来Compare-Object将比较两个数组$fileA$fileB. 通常Compare-Object只会返回不同的对象并指示它们是在哪一侧找到的

InputObject SideIndicator
----------- -------------
Squirrel    =>      # found only in $fileB
Dog         <=      # found only in $fileA
Fish        <=      # found only in $fileA

通过添加-ExcludeDifferentand-IncludeEqual标记,我们强制Compare-Object只返回使用它在 $fileA 和 $fileB 中找到的值

InputObject SideIndicator
----------- -------------
Big Cat     ==
Monkey      ==

然后我们随意使用这个输出。我想显示它的输出Compare-Object并用它做一些额外的任务,所以我将输出对象通过管道传输到Tee-Object -Variable somevariable. 这会将输出发送到变量并沿着管道向下发送,在这种情况下,它只是输出到主机/屏幕

Compare-Object $fileA $fileB -ExcludeDifferent -IncludeEqual | 
    Tee-Object -Variable compareObject  # set the $compareObject variable with results of Compare-Object 
                                        # and send down the pipe to host/screen

最后,我们遍历这两个对象,它Compare-Object让我们发现它在两个数组中都相等,并使用 InputObject 属性制定我们的消息字符串(如您在上面看到的包含我们正在寻找的值)

$compareObject | ForEach-Object -Begin { "`n" } -Process { "Found $($_.InputObject) in both files!" }

奖金

作为奖励,我最初认为 OP 想要比较包括管道在内的行中的项目,所以我写了这个。唯一的区别是我使用正则表达式在所有空格和管道中查找术语,包括来自的所有比较Compare-Object,并且最后不输出额外的字符串

$file1 = "| Dog | | Big Cat | | Fish | | Monkey | "
$file2 = "| Monkey | | Big Cat | | Squirrel |"

$matches1 = $file1 | Select-String -AllMatches  '\|\s?(\w*\s?\w*)\s?\|\s?'
$file1Terms = foreach ($match in ($matches1.Matches)){ $match.Groups[1].Value.Trim() }
$matches2 = $file2 | Select-String -AllMatches  '\|\s?(\w*\s?\w*)\s?\|\s?'
$file2Terms = foreach ($match in ($matches2.Matches)){ $match.Groups[1].Value.Trim()  }

Compare-Object $file1Terms $file2Terms -IncludeEqual

输出

InputObject SideIndicator
----------- -------------
Big Cat     ==
Monkey      ==
Squirrel    =>
Dog         <=
Fish        <=

推荐阅读