PDA

Показать полную графическую версию : [решено] Необходимо реализовать задачу с расчётом хеша в директориях и сохранением в фаил.


Страниц : [1] 2

DjBoBo
17-12-2013, 09:25
Мне это необходимо для автоматизированного бекапа через программу GoodSync, там можно выполнять команды до синхронизации(бекапа).
Так вот я хочу чтобы перед синхронизацией создавался по всем правилам созданный фаил с контрольной суммой всех файлов в директории и поддиректориях, исключая при этом файлы Thumbs.db (и не только, зависит от конкретной бекап-задачи). Причём чтобы была возможность сохранять этот фаил со списком контрольных сумм файлов в произвольном месте а не сканируемой директории.

Искал консольные утилиты для расчёта контрольных сумм, но так и не нашёл таких, в которых было бы возможно задавать исключения для определённых имён файлов.

Iska
17-12-2013, 09:48
Искал консольные утилиты для расчёта контрольных сумм, но так и не нашёл таких, »
Есть.

в которых было бы возможно задавать исключения для определённых имён файлов. »
И не надо.

1. Какая конкретно контрольная сумма нужна?
2. Какая ОС?

DjBoBo
17-12-2013, 09:49
Iska,
1 MD5
2 Windows XP, Windows 7.

Iska
17-12-2013, 10:20
Думаю, для вычисления удобнее всего будет использовать скрипт на PowerShell, скажем: Use PowerShell To Calculate the Hash of a File | Learn Powershell | Achieve More (http://learn-powershell.net/2013/03/25/use-powershell-to-calculate-the-hash-of-a-file/) и т.п.

DjBoBo
17-12-2013, 10:43
Iska, боюсь мне самому не осилить скриптовый язык :-(

Iska
17-12-2013, 12:01
function GetMD5Hash([System.String]$sFile) {
$oHashAlgorithm = [Security.Cryptography.HashAlgorithm]::Create("MD5")

$oStreamReader = ([System.IO.StreamReader]$sFile).BaseStream

-join ($oHashAlgorithm.ComputeHash($oStreamReader) | ForEach-Object -Process { "{0:x2}" -f $_ })
$oStreamReader.Close()
}

$sRootPath = "E:\Песочница\0328"
$sMD5ListPath = "E:\Песочница\0336\MD5 List.txt"

Get-ChildItem -Path $sRootPath -Recurse |`
Where-Object -FilterScript { -not $_.PSIsContainer -and "Thumbs.db", "Descript.ion" -notcontains $_.Name } |`
ForEach-Object -Process {
"$(GetMD5Hash $_.FullName)`t$($_.FullName)"
} | Out-File -FilePath $sMD5ListPath -Encoding Unicode

DjBoBo
17-12-2013, 13:11
Iska, спасибо. Вот только необходимо чтобы пути были относительными. Так как бекапы на удалённом устройстве располагаются по другим путям. Да и если их верифицировать на основном компьютере всё равно они будут лежать по другим путям.

Сейчас всё отображается вот так
C:\Test\123.txt
C:\Test\sync\test1.jpg
C:\Test\sync\test2.jpg

а необходимо вот так.
*123.txt
*sync\test1.jpg
*sync\test2.jpg

И хотелось бы в начале списка дату со временем, например
; Generated on 2013-12-17 at 13:00:00

Iska
17-12-2013, 19:11
Пробуйте:
function GetMD5Hash([System.String]$sFile) {
$oHashAlgorithm = [Security.Cryptography.HashAlgorithm]::Create("MD5")

$oStreamReader = ([System.IO.StreamReader]$sFile).BaseStream

-join ($oHashAlgorithm.ComputeHash($oStreamReader) | ForEach-Object -Process { "{0:x2}" -f $_ })
$oStreamReader.Close()
}

$sRootPath = "E:\Песочница\0328"
$sMD5ListPath = "E:\Песочница\0336\MD5 List.txt"

"; Generated on $(Get-Date)" | Out-File -FilePath $sMD5ListPath -Encoding Unicode

Get-ChildItem -Path $sRootPath -Recurse |`
Where-Object -FilterScript { -not $_.PSIsContainer -and "Thumbs.db", "Descript.ion" -notcontains $_.Name } |`
ForEach-Object -Process {
"$(GetMD5Hash $_.FullName)`t$($_.FullName.Substring($sRootPath.Length + 1))"
} | Out-File -FilePath $sMD5ListPath -Encoding Unicode -Append

DjBoBo
18-12-2013, 01:22
Iska, результирующий файл контрольных сумм не воспринимает программа чекер из-за двух моментов.
Первый момент заключается в том что фаил использует какую-то экзотическую кодировку UCS-2 Little Endian (согласно Notepad++) за место UTF-8.
И второй момент заключается в том что между контрольной суммой и именем файла стоит символ не пробела (а Tab?).
Я в Notepad++ преобразовал фаил в UTF-8, сменил удлинённый пробел на обычный и вроде как всё работает.

Надеюсь что это можно исправить в самом скрипте :-)

Iska
18-12-2013, 01:46
фаил использует какую-то экзотическую кодировку UCS-2 Little Endian »
Это наиобычнейший юникод ;). Вы ранее ничего не упоминали про кодировку, посему я выбирал сам.

И второй момент заключается в том что между контрольной суммой и именем файла стоит символ не пробела (а Tab?). »
И по этому поводу ранее ничего не было сказано. Вообще у Вас там были звёздочки ;).

Надеюсь что это можно исправить в самом скрипте :-) »
Пробуйте:
function GetMD5Hash([System.String]$sFile) {
$oHashAlgorithm = [Security.Cryptography.HashAlgorithm]::Create("MD5")

$oStreamReader = ([System.IO.StreamReader]$sFile).BaseStream

-join ($oHashAlgorithm.ComputeHash($oStreamReader) | ForEach-Object -Process { "{0:x2}" -f $_ })
$oStreamReader.Close()
}

$sRootPath = "E:\Песочница\0328"
$sMD5ListPath = "E:\Песочница\0336\MD5 List.txt"

"; Generated on $(Get-Date)" | Out-File -FilePath $sMD5ListPath -Encoding UTF8

Get-ChildItem -Path $sRootPath -Recurse |`
Where-Object -FilterScript { -not $_.PSIsContainer -and "Thumbs.db", "Descript.ion" -notcontains $_.Name } |`
ForEach-Object -Process {
"$(GetMD5Hash $_.FullName) $($_.FullName.Substring($sRootPath.Length + 1))"
} | Out-File -FilePath $sMD5ListPath -Encoding UTF8 -Append

AMDBulldozer
18-12-2013, 03:04
echo Generated on `date` > /var/log/md5.hashes; find $DIR_TO_BACKUP -type f \! -name Thumbs.db -exec md5sum {} \; >> /var/log/md5.hashes
Правда это не для Windows...

DjBoBo
18-12-2013, 12:36
Вы ранее ничего не упоминали про кодировку »

И по этому поводу ранее ничего не было сказано »

Всё тестируется по факту, заведомо не мог знать как обработает черкер выходной фаил :-)

Я радовался, радовался. А потом понял что скрипт и так не обрабатывает Thumbs.db, и не потому что в списках исключения а потому что имеет скрытый атрибут (и возможно системный?) . И соответственно другие файлы с атрибутом "скрытый" тоже :-(

Это можно как-нибуть излечить?

И ещё если это возможно очень бы хотелось чтобы в комментарии прописывалось общее число просканированных файлов. Что то вроде такого.
; Generated on 03/03/2013 02:37:09
; Scanned files: 3563

А если уж совсем идеально, то можно добавить к просканированным файлам ещё и общее количество (с учётом исключений). Например вот так.
; Generated on 03/03/2013 02:37:09
; Scanned files: 3563
; Total files: 3572

--- UPD ---
И обмозговав свои будущие проекты я понял что мне необходимо исключать не только файлы но и папки.
Быть может стоит вынести в переменную в начало файла-скрипта некий список?
Я не знаю как это сделать, но примерно я представляю это так.
%files%
Thumbs.db
Descript.ion

%folders%
D:\Workfolder\Caсhe\ (или с относительными путями к сканируемой корневой папке)
D:\TestSun\Profile\Temp\
и так далее каждый новый объект с новой строчки.

Соответственно наверное если реализовать это то предложение с подсчётом исключённых файлов и самое главное папок уже будет не столь состоятельным. Ну если эта фича сложна в реализации то без неё проживу :-)
Главное это подсчёт всех файлов (включая скрытые и системные) и введение исключений и на папки.

AMDBulldozer
18-12-2013, 13:26
{
echo "; Generated on `date`"
echo "; Scanned files: `find $DIR_TO_BACKUP -type f \! -name Thumbs.db | wc -l`"
echo "; Total files: `find $DIR_TO_BACKUP -type f | wc -l`"
find $DIR_TO_BACKUP -type f \! -name Thumbs.db -exec md5sum {} \;
} > /var/log/md5.hashes

Опять-таки не для Windows :sorry:

DjBoBo
18-12-2013, 14:53
AMDBulldozer, спасибо конечно. Но я использую исключительно Windows :-) Хотелось бы закончить этот "проект века" наконец и забекапить по всем правилам и своим внутренним критериям все свои многочисленные файлы :-)

Iska
19-12-2013, 00:40
Я радовался, радовался. А потом понял что скрипт и так не обрабатывает Thumbs.db, и не потому что в списках исключения а потому что имеет скрытый атрибут (и возможно системный?) . И соответственно другие файлы с атрибутом "скрытый" тоже :-( Это можно как-нибуть излечить?»
Выходит, что так:
-Force

Allows the cmdlet to get items that cannot otherwise not be accessed by the user, such as hidden or system files.
Я тоже учусь.

И ещё если это возможно очень бы хотелось чтобы в комментарии прописывалось общее число просканированных файлов. Что то вроде такого.
; Generated on 03/03/2013 02:37:09
; Scanned files: 3563
А если уж совсем идеально, то можно добавить к просканированным файлам ещё и общее количество (с учётом исключений). Например вот так.
; Generated on 03/03/2013 02:37:09
; Scanned files: 3563
; Total files: 3572 »
Я посмотрю, что можно сделать. Но логику всю придётся переделывать.

И обмозговав свои будущие проекты я понял что мне необходимо исключать не только файлы но и папки.
Быть может стоит вынести в переменную в начало файла-скрипта некий список?
Я не знаю как это сделать, но примерно я представляю это так.
%files%
Thumbs.db
Descript.ion
%folders%
D:\Workfolder\Caсhe\ (или с относительными путями к сканируемой корневой папке)
D:\TestSun\Profile\Temp\
и так далее каждый новый объект с новой строчки.
Соответственно наверное если реализовать это то предложение с подсчётом исключённых файлов и самое главное папок уже будет не столь состоятельным. Ну если эта фича сложна в реализации то без неё проживу :-)
Главное это подсчёт всех файлов (включая скрытые и системные) и введение исключений и на папки. »
Без подсчёта исключённых будет много проще. Поясните про относительные пути, ибо логика разная.

DjBoBo
19-12-2013, 02:13
Iska, Огромное спасибо что помогаете мне в реализации, ваша помощь бесценна :-)
Подсчёт исключённых действительно был бы избыточен, желательно просто реализовать подсчёт общего количества просканированных файлов и соответственно хеш-записей. И не более.
Касаемо же путей, я просто подумал если в скрипте указывается жёстко рабочая папка, то наверное при написании папок-исключений необходимо отталкиваться относительно её, а это значит пути будут относительными. Хотя конечно окончательный выбор за вами. В моём случае сканируемые папки на компьютере не перемещаются.
Но в тоже время относительно вывода (хеш-файла) ничего не меняется, там так и должны быть относительные пути.

Iska
20-12-2013, 05:02
Пробуйте:
function GetMD5Hash([System.String]$sFile) {
$oHashAlgorithm = [Security.Cryptography.HashAlgorithm]::Create("MD5")

$oStreamReader = ([System.IO.StreamReader]$sFile).BaseStream

-join ($oHashAlgorithm.ComputeHash($oStreamReader) | ForEach-Object -Process { "{0:x2}" -f $_ })
$oStreamReader.Close()
}

$sRootPath = "E:\Песочница\0328"
$sMD5ListPath = "E:\Песочница\0336\MD5 List.txt"
$sExcludeFiles = "E:\Песочница\0336\ExcludeFiles.txt"
$sExcludeFolders = "E:\Песочница\0336\ExcludeFolders.txt"


$cExcludeFiles = @(Get-Content -Path $sExcludeFiles -Encoding UTF8)
$cExcludeFolders = @(Get-Content -Path $sExcludeFolders -Encoding UTF8)


$cList = Get-ChildItem -Path $sRootPath -Recurse -Force |`
Where-Object -FilterScript { -not $_.PSIsContainer -and $cExcludeFiles -notcontains $_.Name }

foreach($elem in $cExcludeFolders) {
$cList = $cList | Where-Object -FilterScript { -not $_.FullName.StartsWith("$sRootPath\$elem") }
}

"; Generated on $(Get-Date)", "; Total files: $($cList.Length)", ( $cList | ForEach-Object -Process {
"$(GetMD5Hash $_.FullName) $($_.FullName.Substring($sRootPath.Length + 1))"
} ) | Out-File -FilePath $sMD5ListPath -Encoding UTF8
Касаемо же путей, я просто подумал если в скрипте указывается жёстко рабочая папка, то наверное при написании папок-исключений необходимо отталкиваться относительно её, а это значит пути будут относительными. »
Да. И без замыкающего обратного слэша (т.е. «Exclude Folder 01», «Exclude Folder 02», «Exclude Folder 03\Folder4\Folder5» и т.п.).

DjBoBo
20-12-2013, 07:42
Iska, Спасибо :-)
Прогнал скрипт в типичных задачах и вроде всё работает :-)
Единственный вопрос возник по этому поводу
Да. И без замыкающего обратного слэша (т.е. «Exclude Folder 01», «Exclude Folder 02», «Exclude Folder 03\Folder4\Folder5» и т.п.). »
Если без слеша в конце то папка воспринимается как Exclude Folder 01* Т.е. если есть например ещё папка Exclude Folder 01Test то она тоже будет исключена. А если поставить слеш то нет. Также я попробовал в исключения папок добавлять пути до файла, например Test\Test.txt и это тоже вполне работает.

Iska
20-12-2013, 08:00
Если без слеша в конце то папка воспринимается как Exclude Folder 01* Т.е. если есть например ещё папка Exclude Folder 01Test то она тоже будет исключена. »
Не додумал. Странно, печально, но факт. Поправил:
function GetMD5Hash([System.String]$sFile) {
$oHashAlgorithm = [Security.Cryptography.HashAlgorithm]::Create("MD5")

$oStreamReader = ([System.IO.StreamReader]$sFile).BaseStream

-join ($oHashAlgorithm.ComputeHash($oStreamReader) | ForEach-Object -Process { "{0:x2}" -f $_ })
$oStreamReader.Close()
}

$sRootPath = "E:\Песочница\0328"
$sMD5ListPath = "E:\Песочница\0336\MD5 List.txt"
$sExcludeFiles = "E:\Песочница\0336\ExcludeFiles.txt"
$sExcludeFolders = "E:\Песочница\0336\ExcludeFolders.txt"


$cExcludeFiles = @(Get-Content -Path $sExcludeFiles -Encoding UTF8)
$cExcludeFolders = @(Get-Content -Path $sExcludeFolders -Encoding UTF8)


$cList = Get-ChildItem -Path $sRootPath -Recurse -Force |`
Where-Object -FilterScript { -not $_.PSIsContainer -and $cExcludeFiles -notcontains $_.Name }

foreach($elem in $cExcludeFolders) {
$cList = $cList | Where-Object -FilterScript { -not $_.FullName.StartsWith("$sRootPath\$elem\") }
}

"; Generated on $(Get-Date)", "; Total files: $($cList.Length)", ( $cList | ForEach-Object -Process {
"$(GetMD5Hash $_.FullName) $($_.FullName.Substring($sRootPath.Length + 1))"
} ) | Out-File -FilePath $sMD5ListPath -Encoding UTF8


Также я попробовал в исключения папок добавлять пути до файла, например Test\Test.txt и это тоже вполне работает. »
Угу. Там сравнение шло по началу пути. В исправленном такое работать уже не должно.

DjBoBo
20-12-2013, 08:57
Не додумал. Странно, печально, но факт. Поправил: »
Угу. Там сравнение шло по началу пути. В исправленном такое работать уже не должно. »
Ну если слеш в конце ничего не нарушает, а ещё к тому же и добавляет функционал по выборочному исключению не только папок но и отдельных конечных файлов то меня он вполне устраивает :-)
Думаю его и использовать...




© OSzone.net 2001-2012