Форум программистов, компьютерный форум, киберфорум
PowerShell
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.60/15: Рейтинг темы: голосов - 15, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 13.01.2016
Сообщений: 9

Рекурсивное переименование файлов, md5-хеш которых совпадает с md5-хешем, указанном в списке файлов

11.10.2016, 13:49. Показов 2959. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть файл из двух колонок md5-хеш и имя файла (краткое, с расширением, UTF-8).
Есть каталог с множеством файлов во всевозможных подкаталогах.

Нужна программка, который просчитает md5 всех файлов и, в случае совпадения хеша с табличным значением, даст этому файлу табличное имя. Вне зависимости от расположения файла, т.е. он останется в том же подкаталоге.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.10.2016, 13:49
Ответы с готовыми решениями:

Рекурсивное переименование файлов, совпавших по md5-хешу
Есть файл из двух колонок md5-хеш и имя файла (краткое, с расширением). Есть каталог с множеством файлов во всевозможных подкаталогах. ...

Сравнение md5-сумм с md5-суммами файлов!
Всем доброго времени суток! Помогите реализовать небольшое приложение - вообщем имеется папка "Тест" в этой папке есть 2 файла...

Сравнение файлов по MD5
Доброго времени суток, я бы хотел узнать как реализовать сравнение файлов по MD5 в Visual Studio 2017 C#? А именно где можно достать...

8
96 / 17 / 5
Регистрация: 05.07.2015
Сообщений: 53
12.10.2016, 10:55
вот скрипт. чтобы переименовал нужно убрать -Whatif
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<#
    .SINOPSIS
        [url]https://www.cyberforum.ru/powershell/thread1823882.html[/url]
#>
 
 
param (
    $PathToListMD5,
    $Path = (Join-Path $pwd "tmp")
 
)
 
###################################################### functions
Function Get-ShortName {
param (
    [Parameter(ValueFromPipeline=$true)]
    $Path
)
BEGIN {
    $fso = New-Object -ComObject Scripting.FileSystemObject
}
PROCESS {
    if ($Path.Fullname) { $Path = $Path.fullName}
    if ((Test-Path -LiteralPath $Path) ) {
    
        If (($f = get-item -LiteralPath $Path).psiscontainer) {
            $fso.getfolder($f.fullname).ShortName
        } ELSE {
            $fso.getfile($f.fullname).ShortName
        }
    }
}
}
#####################################################
function Get-Hash {
 
param (
 
    [Parameter(ValueFromPipeline=$true,Position=1)]
    $Path,
 
    [switch]$MD5,
 
    [Switch]$SHA1
)
 
begin {
    $HashService = switch ($true) { 
        $MD5  { new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider  }
        $SHA1 { new-object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider }
        default {new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider  }
    };
}
 
process {
    if ((Test-Path -LiteralPath $Path ) -and -not ($file = (Get-Item -LiteralPath $Path)).psiscontainer) {
        $HashService |
        foreach {
            [System.BitConverter]::ToString( $_.ComputeHash([System.IO.File]::ReadAllBytes($file.FullName)) )
        } | % { $_.replace("-","") }
    }
}
 
 
}
 
 
 
#####################################################
 
$listMD5_str =
if (-not $PathToMD5 -or -not (Test-Path $PathToMD5)) {
@"
"ABOUT_~1.TXT"  E3C3A8D3E50AB0B200C7BE9A14CAA69F
"ADD_AC~1.PS1"  284CBD600443753418ACC3180B7A66C0
"ADD_DR~1.PS1"  379FAF8AA4BC4F7F7A421D0A4A58403A
"ADD_US~1.PS1"  7F4EFBC8EACE900166332A8BD836F0C9
"adsi-2.ps1"    0745024F1E28CF599AA611A21BB6D7C4
"adsi-3.ps1"    044F9B93A3DC9786F85BF612CC15C4C1
"adsi.ps1"  33E1B94E15C69A021A015578EE60D375
"ADSI_A~1.PS1"  1163D3E536712765206C74FD6EFBBB23
"ADSI_M~2.PS1"  D7D7D8F75481F5234AFF486AD4B6D96C
"ADSI_M~3.PS1"  C72AD9206BF00B162495AF2742F23C51
"@
} else { gc $PathToListMD5 }
 
$listMD5 = 
$listMD5_str.split("`n") | 
select @{n="Name";e={$_.split("`t")[0].Trim("""")}},
       @{n="MD5"; e={$_.split("`t")[1].trim()}}
 
##### pipe1
ls $Path | 
where { -not $_.psiscontainer } |
select *, @{n="ShortName";e={Get-ShortName $_.fullname}},
          @{n="MD5";      e={Get-Hash $_.fullname -MD5}} |
foreach {
    $index = ($listMD5 | % { $_.MD5}).IndexOf($_.md5)
    if (-bnot $index) { $_ }
} |
 
select *, @{n="index";e={$index}} |
 
Tee-Object -Variable rename_files |
 
where { $listMD5[$_.index].name -ne $_.name } |
 
foreach {
 
    $ff = Get-Item -LiteralPath $_.FullName
 
    if ($listMD5[$_.index].name -eq $_.shortname) {
        $ff = $ff | Rename-Item -PassThru -NewName ("ff_" + (Get-Random)) -WhatIf #-<-<-------------- убрать -whatif
    }
 
    if (Test-Path ($file_exs = Join-Path $ff.directory $listMD5[$_.Index].Name)) {
        Write-Warning "File ""$file_exs"" already exist"
    } else {
 
 
 
        $ff | Rename-Item -NewName $listMD5[$_.Index].Name -Force -Verbose -WhatIf #-<-<-------------- убрать -whatif
    } 
 
}
 
#### end pipe1
2
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18031 / 7734 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
12.10.2016, 21:40
Цитата Сообщение от bookme Посмотреть сообщение
в случае совпадения хеша с табличным значением
Поиск будет быстрее, если в таблице завести ещё одну колонку - размер файла.
1
Покинул форум
3700 / 1483 / 355
Регистрация: 07.05.2015
Сообщений: 2,903
12.10.2016, 23:01
Цитата Сообщение от Dragokas
Поиск будет быстрее, если в таблице завести ещё одну колонку - размер файла.
А еще быстрее, если файл содержит полный путь и представляет собой CSV-файл. А если серьезно, то, во-первых, поиск будет быстрее, если обратиться к Find[First|Netx]File напрямую, а лучше и вовсе обратиться к NtQueryDirectoryFile; во-вторых, вычисление хэша путем считывания всех байт файла является заведомо порочным путем - лучше использовать FileStream. К слову, в поздних версиях PowerShell есть штатная функция (именно функция, а не командлет) Get-FileHash, так что там даже ничего изобретать не нужно. В-третьих, непонятно для чего автор кода выше стал вдруг использовать COM'ы.
0
0 / 0 / 0
Регистрация: 13.01.2016
Сообщений: 9
13.10.2016, 13:27  [ТС]
Хорошо, колонку заведу, размер в байтах, csv-файл, utf-8, столбцы Filesize, MD5 и Name. Строк в нем действительно очень много.
Только вот с PowerShell не сталкивался раньше, скрипт пока не сработал .

Цитата Сообщение от dirigar Посмотреть сообщение
вот скрипт. чтобы переименовал нужно убрать -Whatif
Попробовал запустить, ошибка
Code
1
2
3
4
5
Произошла ошибка при вызове метода, так как [System.Object[]] не содержит метод с именем "IndexOf".
D:\1\a.ps1:98 знак:46
+     $index = ($listMD5 | % { $_.MD5}).IndexOf <<<< ($_.md5)
    + CategoryInfo          : InvalidOperation: (IndexOf:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
Какие-то параметры и пути нужно указывать в файле?
0
96 / 17 / 5
Регистрация: 05.07.2015
Сообщений: 53
14.10.2016, 13:04
Цитата Сообщение от greg zakharov Посмотреть сообщение
лучше использовать FileStream
спасибо, учел. Благо, что у ComputeHash есть соответствующая перегрузка.
Цитата Сообщение от bookme Посмотреть сообщение
Попробовал запустить, ошибка
В вашей версии Posh( $host.version) нет метода indexof для массива объектов (
PowerShell
1
,@() | gm indexof
)
По другому сделал. должно работать. но нужно указать файл с мд5 и папку с файлами. (пройдет рекурсивно)
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<#
    .SINOPSIS
        [url]https://www.cyberforum.ru/powershell/thread1823882.html[/url]
#>
 
 
param (
 
    [ValidateScript({Test-Path -LiteralPath $_})]
    $PathToListMD5 = "C:\Profiles\denis\YandexDisk\script\ps\md5.txt",
 
    [ValidateScript({Test-Path -LiteralPath $_})]
    $Path = (Join-Path $pwd "tmp")
 
)
 
###################################################### functions
 
function Get-Hash {
 
param (
 
    [Parameter(ValueFromPipeline=$true,Position=1)]
    $Path,
 
    [switch]$MD5,
 
    [Switch]$SHA1
)
 
begin {
    $HashService = switch ($true) { 
        $MD5  { new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider  }
        $SHA1 { new-object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider }
        default {new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider  }
    };
}
 
process {
    if ($Path.Fullname) { $Path = $Path.fullName}
    $hash = if ((Test-Path -LiteralPath $Path ) -and -not ($file = (Get-Item -LiteralPath $Path)).psiscontainer) {
        $HashService |
        foreach {
            #[System.BitConverter]::ToString( $_.ComputeHash([System.IO.File]::ReadAllBytes($file.FullName)) )
 
            [System.BitConverter]::ToString( $_.ComputeHash(($read = $file.OpenRead())) )
 
        } |
        foreach { $_.replace("-","") }
    } else {Write-Warning "$Path - File not found" }
    $read.Close()
    $read.Dispose()
 
    Write-Output $hash
        
}
 
 
}
 
 
 
###########################################
 
##### pipe1
ls $Path -Recurse -Force | 
where { -not $_.psiscontainer } |
foreach { $file = $_ ;  $_ } |
Get-Hash |
foreach {
    Select-String "^\s*(.*)\s*\b($([regex]::Escape($_))\w*)\b" -List -path $PathToListMD5
} | 
 
where { ( $new_name = $_.matches[0].groups[1].value.trim(" `"`t")) -ne $file.name } |
 
foreach {
    $shortName =      ##p2
    gwmi cim_datafile -Filter "name=""$($file.fullname.Replace("",""))""" |
    select -ExpandProperty EightDotThreeFileName |
    Split-Path -Leaf; ##end p2
    
    #Write-Host "shortname = $shortName`t file = $($file.directory)`t new_name = ---$new_name----"
    
    $ff = $file
    if ($new_name -eq $shortname) {
        $ff = $ff | Rename-Item -PassThru -NewName ("ff_" + (Get-Random)) -WhatIf #-<-<-------------- убрать -whatif
    }
 
    if (Test-Path ($file_exs = Join-Path $ff.directory $new_name) ) {
        Write-Warning "File ""$file_exs"" already exist"
    } else {
        $ff | Rename-Item -NewName $new_name -Force -Verbose -WhatIf #-<-<-------------- убрать -whatif
    } 
 
}
 
#### end pipe1
0
Покинул форум
3700 / 1483 / 355
Регистрация: 07.05.2015
Сообщений: 2,903
14.10.2016, 14:06
dirigar, что за поток сознания?
0
0 / 0 / 0
Регистрация: 13.01.2016
Сообщений: 9
14.10.2016, 19:06  [ТС]
Вот для примера ex1.csv с колонками размер, md5, новое имя файла. В архиве также лежат сами файлы для тестирования.
Уточните, пожалуйста, где указывать путь к папке, в параметрах видел только путь к файлу с хешами.
Вложения
Тип файла: zip ex1.zip (2.0 Кб, 6 просмотров)
0
96 / 17 / 5
Регистрация: 05.07.2015
Сообщений: 53
16.10.2016, 15:19
Не много подправил.
текущая папка должна быть равна папке где лежат файлы, или указать полные пути к параметрам.
проверку на размер не реализовал, т.к. исхожу из того что файл в папке может быть под другим именем (что в примере), следовательно, вычислять хеш все равно придется для всех файлов.
насчет краткого имени, я так понял что это имя файла в формате 8-знаков, "длинное_имя.txt" -> "13757~1.txt". но видно не так понял, так что убрал из скрипт его вычисление.
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<#
    .SINOPSIS
        [url]https://www.cyberforum.ru/powershell/thread1823882.html[/url]
        Есть файл из двух колонок md5-хеш и имя файла (краткое, с расширением, UTF-8).
        Есть каталог с множеством файлов во всевозможных подкаталогах.
 
        Нужна программка, который просчитает md5 всех файлов и, в случае совпадения хеша с табличным значением,
         даст этому файлу табличное имя. Вне зависимости от расположения файла, т.е. он останется в том же подкаталоге.
 
 
         +
         файл формата csv md5, filename
 
#>
 
 
param (
    #если текущая папка равна ex1 ($pwd = "полный путь к ex1")
    [ValidateScript({Test-Path -LiteralPath $_})]
    $PathToListMD5 = ".\ex1.csv" ,
 
    [ValidateScript({Test-Path -LiteralPath $_})]
    $Path = ".\подкаталог для примера"
 
)
 
###################################################### functions
 
function Get-Hash {
 
param (
 
    [Parameter(ValueFromPipeline=$true,Position=1)]
    $Path,
 
    [switch]$MD5,
 
    [Switch]$SHA1
)
 
begin {
    $HashService = switch ($true) { 
        $MD5  { new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider  }
        $SHA1 { new-object -TypeName System.Security.Cryptography.SHA1CryptoServiceProvider }
        default {new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider  }
    };
}
 
process {
    if ($Path.Fullname) { $Path = $Path.fullName}
    $hash = if ((Test-Path -LiteralPath $Path ) -and -not ($file = (Get-Item -LiteralPath $Path)).psiscontainer) {
        $HashService |
        foreach {
            #[System.BitConverter]::ToString( $_.ComputeHash([System.IO.File]::ReadAllBytes($file.FullName)) )
 
            [System.BitConverter]::ToString( $_.ComputeHash(($read = $file.OpenRead())) )
 
        } |
        foreach { $_.replace("-","") }
    } else {Write-Warning "$Path - File not found" }
    $read.Close()
    $read.Dispose()
 
    Write-Output $hash
        
}
 
 
}
 
 
 
###########################################
$listMD5  = Import-Csv $PathToListMD5
 
##### pipe1
ls $Path -Recurse -Force | 
where { -not $_.psiscontainer } |
foreach { $file = $_ ;  $_ } |
Get-Hash |
foreach {
    $hash = $_
    $new_name = 
    $listMD5 | ? { $_.md5.trim() -eq $hash.trim() } | select -First 1 -ExpandProperty file_name
    $new_name
} | 
 
where { $_ } |
 
where { $_ -ne $file.name } |
 
foreach {
    if (Test-Path ($file_exs = Join-Path $file.directory $new_name) ) {
 
        Write-Warning "File ""$file_exs"" already exist"
    
    } else {
        $file | Rename-Item -NewName $new_name -Force -Verbose -WhatIf #-<-<-------------- убрать -whatif
    } 
 
}
 
#### end pipe1
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
16.10.2016, 15:19
Помогаю со студенческими работами здесь

Провести инвентаризацию файлов с использованием MD5
вот какое задание дали, а я только начинающая! прошу ,как это реализовать на си++? :cry: инструкция: 1. Взять конкретный каталог...

[FAQ] Организация проверки файлов по MD5
В этой теме я расскажу простой и удобный способ сравнения файлов по MD5. Начну по порядку: Чаще всего это используется для игровых...

Вычислить MD5 папки и всех файлов в ней
Всем доброго времени суток.Возникла необходимость вычистить md5 папки и её содержимого. Заранее спасибо.

Получение md5 и размера файлов в папках и подпапках
Есть путь до папки, в которой нужно найти все подпапки и файлы и обрезать чусть пути. С помощью данного метода я создаю файл с содержимым...

OutOfMemory при сравнении MD5 нескольких больших файлов
Доброго времени суток. Пилю программу файловой односторонней синхронизации заточенную под нужды организации. Есть некий список...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru