Лучший способ экспортировать вывод в столбцы, а не в строки, используя метод Export-Csv в PowerShell для сравнения хэшей файлов в Excel - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть две папки (Fold1 и Fold2) с множеством файлов в разных форматах (.doc, .pdf, .xml, .html) в них, и общее количество элементов (файлов) может варьироваться в каждой папке.Я пытаюсь сравнить контрольные суммы MD5 для каждого файла, присутствующего в обеих папках, и для файлов, которые являются дополнительными в обеих папках, просто перечислите их контрольные суммы, чтобы я мог скопировать / проверить эти файлы позже.

Этогде я достиг:

$path1 = "C:\Users\username\Desktop\Fold1"
$path2 = "C:\Users\username\Desktop\Fold2"

$Data1 = dir "C:\Users\username\Desktop\Fold1" -Recurse |
         Where-Object {!$_.PSIsContainer} |
         Get-FileHash -Algorithm MD5  |
         select @{n='Hash';e={$_.Hash}}, @{n='File';e={Split-Path $_.Path -Leaf}}

$Data2 = dir "C:\Users\username\Desktop\Fold2" -Recurse |
         Where-Object {!$_.PSIsContainer} |
         Get-FileHash -Algorithm MD5  |
         select @{n='Hash';e={$_.Hash}}, @{n='File';e={Split-Path $_.Path -Leaf}}

$Full = foreach ($d in $Data1) {
    $d | Select-Object Hash, File,@{n="Hash2";e={
        ($Data2 | Where-Object File -eq $d.File).Hash
    }}
}

$Full | Export-Csv .\report.csv

Это дает следующий вывод:

Output Screenshot 1

Задача 1:

Поскольку я использую Where-Object File -eq $d.File, так что на всякий случай, если в папке 2 есть один дополнительный файл, чем в папке 1, в таком случае он не будет захватывать дополнительный файл, и сравнение пойдет не так, потому что мне нужно захватитьвсе предметы независимо.Чтобы избежать этого, я попытался добавить .Count, который выглядит следующим образом:

$Data1Count = (Get-ChildItem -File -Path $path1).Count
$Data2Count = (Get-ChildItem -File -Path $path2).Count

if ($Data1Count -gt $Data2Count) {
    $Full = foreach ($d in $Data1) {
        $d | Select-Object Hash,File,@{n="Hash2";e={
            ($Data2 | Where-Object File -eq $d.File).Hash
        }}
    }
    $Full
} elseif ($Data2Count -gt $Data1Count) {
    $Full = foreach ($d in $Data2) {
        $d | Select-Object Hash,File,@{n="Hash2";e={
            ($Data1 | Where-Object File -eq $d.File).Hash
        }}
    }
    $Full
} else {
    $Full = foreach ($d in $Data1) {
        $d | Select-Object Hash,File,@{n="Hash2";e={
            ($Data2 | Where-Object File -eq $d.File).Hash
        }}
    }
    $Full
}

Задача 2:

Этот метод перечисляет все элементы (файлы) из одногоиз папок (Folder1 или Folder2), в зависимости от того, какое число файлов больше, но все равно не перечисляются дополнительные файлы в другой папке.Просто чтобы показать вам, вот структура каталогов:

Directories Screenshot

и это вывод (так как количество файлов в папке 2 равно> Папка 1):

Output Screenshot 2

То, что я пытаюсь достичь, это что-то вроде следующего в качестве результата сравнения, в котором перечислены все соответствующие файлы, а также дополнительные файлыв любой папке:

Screenshot of Excel Table

1 Ответ

0 голосов
/ 16 сентября 2018

То, что вы пытаетесь сделать, это не то, как вы бы справились с чем-то подобным в PowerShell.Надлежащим способом решения этой проблемы будет перечисление файлов, как вы делаете в первом примере кода, а затем сравнение списков с Compare-Object:

Compare-Object $Data1 $Data2 -Property Hash -IncludeEqual -PassThru

, что даст вам вывод, подобный этому:

Hash                             File   SideIndicator
----                             ----   -------------
1DA53AC45042DB9413D1A6F055F7C5BA a.docx ==
2E9D15DF495521763D6CD5090B7DEF48 b.pdf  ==
8DA3E12E4908F49055BD679D68848D5A c.pdf  =>
6F0D8230A93276D335CE656CEB54B764 d.doc  <=

Затем вы можете использовать боковой индикатор для преобразования данных следующим образом:

Compare-Object $Data1 $Data2 -IncludeEqual -Property Hash -PassThru |
    Select-Object @{n='Hash';e={if ($_.SideIndicator -ne '=>') {$_.Hash}}},
        @{n='File';e={if ($_.SideIndicator -ne '=>') {$_.File}}},
        @{n='Hash2';e={if ($_.SideIndicator -ne '<=') {$_.Hash}}},
        @{n='File2';e={if ($_.SideIndicator -ne '<=') {$_.File}}}

, что приведет к выводу следующим образом:

Hash                             File   Hash2                            File2
----                             ----   -----                            -----
1DA53AC45042DB9413D1A6F055F7C5BA a.docx 1DA53AC45042DB9413D1A6F055F7C5BA a.docx
2E9D15DF495521763D6CD5090B7DEF48 b.pdf  2E9D15DF495521763D6CD5090B7DEF48 b.pdf
                                        8DA3E12E4908F49055BD679D68848D5A c.pdf
6F0D8230A93276D335CE656CEB54B764 d.doc

или преобразовать данные следующим образомthis:

Compare-Object $Data1 $Data2 -IncludeEqual -Property Hash -PassThru |
    Select-Object Hash, File,
        @{n=$path1;e={if ($_.SideIndicator -ne '=>') {'X'}}},
        @{n=$path2;e={if ($_.SideIndicator -ne '<=') {'X'}}}

, что даст результат, подобный следующему:

Hash                             File   C:\...\Fold1 C:\...\Fold2
----                             ----   ------------ ------------
1DA53AC45042DB9413D1A6F055F7C5BA a.docx X            X
2E9D15DF495521763D6CD5090B7DEF48 b.pdf  X            X
8DA3E12E4908F49055BD679D68848D5A c.pdf               X
6F0D8230A93276D335CE656CEB54B764 d.doc  X

Затем экспортируйте этот вывод в CSV через Export-Csv.

...