PDA

Показать полную графическую версию : [решено] Удаление одинаковых файлов по размеру


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

Arsenik77
16-07-2011, 10:41
Добрый день, нужен батник который сравнивал и удалял одинаковые по размеру файлы в одной папке (и оставлял только один).
Сторонние программы не хочу использовать, нужно именно bat.

root221
16-07-2011, 11:49
@Echo off
set Size=66
set Files=C:\help\*.*
rem Если размер должен быть равным или меньшим Size, то EQU заменить на LEQ
for %%L in (%Files%) do if /i %%~zL EQU %Size% del /f "%%L"

Iska
16-07-2011, 12:41
Сторонние программы не хочу использовать, нужно именно bat. »
Как насчёт скрипта VBScript?
Option Explicit

Dim objFSO
Dim strFolder
Dim objFile
Dim objDictionary
Dim elem


If WScript.Arguments.Count = 1 Then
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

strFolder = WScript.Arguments.Item(0)

If objFSO.FolderExists(strFolder) Then
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")

For Each objFile In objFSO.GetFolder(strFolder).Files
If objDictionary.Exists(objFile.Size) Then
If objDictionary.Item(objFile.Size) <> "" Then
objFSO.DeleteFile objDictionary.Item(objFile.Size), True
objDictionary.Item(objFile.Size) = ""
End If

objFSO.DeleteFile objFile.Path, True
Else
objDictionary.Add objFile.Size, objFile.Path
End If
Next

objDictionary.RemoveAll

Set objDictionary = Nothing
Else
WScript.Echo "Folder [" & strFolder & "] not found."
End If

Set objFSO = Nothing
Else
WScript.Echo "Usage: " & WScript.ScriptName & " <folder>"
End If

WScript.Quit 0

Путь к папке указываем аргументом скрипта.

Iska
16-07-2011, 13:01
PowerShell:
param (
[string]$Folder = "E:\Песочница\0061\*"
)
Get-ChildItem -Path $Folder | `
Where-Object -FilterScript { -not $_.PSIsContainer } | `
Group-Object -Property Length | `
Where-Object -FilterScript { $_.Count -gt 1 } | `
ForEach-Object -Process {
Remove-Item $_.Group
}

Arsenik77
16-07-2011, 14:51
root221, мне надо чтоб файлы сравнивались между собой (по размеру), а не по конкретному размеру.
Я, в скриптах нуль.
Iska, скрипт полностью удаляет все файлы в папке.

Foreigner
16-07-2011, 15:07
Arsenik77,
Еще вариант:

@echo off
setlocal enabledelayedexpansion

pushd "c:\test" || goto:eof

for /f "tokens=*" %%i in ('dir /b /a-d') do call:1 "%%i"
for /f "tokens=2 delims==" %%i in ('set todel_') do echo del %%i %%~zi

popd
goto:eof

:1
if not defined file_%~z1 (

set "file_%~z1=%1"

) else (

echo del !file_%~z1! %~z1
set "file_%~z1=%1"
set "todel_%~z1=%1"

)

То что красным удалишь после проверки, зеленым исправишь на своё

Arsenik77
16-07-2011, 16:11
Foreigner, не работает, написал "Непредвиденное появление: .jpg" (сравниваю jpg)

megaloman
16-07-2011, 16:43
Задача не очень четко поставлена. Вот решение, удаляем все одинаковые по размеру файлы.@Echo Off

Set Otkuda=D:\Delete
Set S1=-1

FOR /F "usebackq delims=" %%f IN (`Dir /B /A:-D /O:SN "%Otkuda%\"`) DO Call :DelSize "%Otkuda%\%%f"
GoTo :Eof

:DelSize
Set S2=%~z1

If %S1% NEQ %S2% (
Set S1=%S2%
Set N1=%1
) Else (
Del %1
If Exist %N1% Del %N1%
)
Если надо по одному файлу из тех, у которых размер одинаков, оставить, то строку

If Exist %N1% Del %N1%

следует удалить.

ferget
16-07-2011, 17:02
"Непредвиденное появление: .jpg" (сравниваю jpg) »

вы так одинаковые изображения хотите удалить?

Foreigner
16-07-2011, 17:13
Arsenik77,

Мой батник удаляет все одинаковые по размеру файлы, независимо от расширения. Если есть например три файла размером 123 и семь файлов размером 321, то он их всех удалит, но оставит файл размером 124, т.к. он один такого размера. В батнике надо указать только папку, в которой сравнивать.

Добрый день, нужен батник который удалял одинаковые по размеру файлы в одной папке. »

Arsenik77
16-07-2011, 17:38
root221, Iska, Foreigner, megaloman, - СПАСИБО!
megaloman - работает.

kiripanda
16-07-2011, 17:47
Удаление дубликатов по хешу (http://forum.wincmd.ru/viewtopic.php?p=80462#80462)

Arsenik77
16-07-2011, 18:15
megaloman, поторопился немного, bat-к работает, но как-то выборочно. Проверил на 5000 файлов в папке, батник удаляет, но не всЁ.

Примерно разобрался в чем дело, на файлах где есть в арабские (китайские) или другие не типичные символы батник затыкаеться.
типа XXXXXXXXXXXXX_Штукатурка.jpg
Нужно чтоб батник переименовывал их, во что нибудь типа XXXXXXXXXXXXX_yyyyy.jpg, где XXXXXXXXXXXXX - важные символы, yyyyy неважно.

Батник будет проверять по 100-200 тыс.файлов.

Iska
16-07-2011, 20:26
Iska, скрипт полностью удаляет все файлы в папке. »
Arsenik77, какой скрипт из двух? У меня работают оба варианта.

Если Вам нужно искать и удалять дубликаты — то это совсем другой разговор, например, «CloneSpy» или «Duplicate Files Finder», або что-то своё — в зависимости от конкретной задачи и условий применения.

Arsenik77
16-07-2011, 20:30
Iska, работает VBScript, PowerShell не понял как запускать.
Но только надо по одному файлу из тех, у которых размер одинаков, оставить.

Скрипт также работает с "трудными" именами файлов.

megaloman
16-07-2011, 20:56
Попробуйте вариант решения, но при таком большом числе файлов не уверен, как сработает сортировка в Dir. Я попробовал на 50000 файлов, но они небольшого размера @Echo Off

Set Otkuda=E:\dddddddd
Set S1=-1

FOR /F "usebackq delims=" %%f IN (`Dir /B /A:-D /O:S "%Otkuda%\"`) DO Call :DelSize "%Otkuda%\%%f"
GoTo :Eof

:DelSize
Set S2=%~z1

If %S1% NEQ %S2% (
Set S1=%S2%
) Else (
Del %1
)

Arsenik77
16-07-2011, 21:29
megaloman, работает с нормальным именами файлов, затык идет на таких именах у файло⠨тукатурка.jpg

Foreigner
16-07-2011, 21:52
Arsenik77,
Попробуй такой вариант, правда на большом кол-ве файлов не проверял:

@echo off
setlocal

pushd "c:\test\folder" || goto:eof
for /f "tokens=*" %%i in ('dir /b /a-d') do call:del "%%~fi"
popd
goto:eof

:del
set "file=%~1"

2>nul 1>nul (

wmic datafile where "path='\\test\\folder\\' and filesize='%~z1' and not name='%file:\=\\%'" call delete

)

Arsenik77
16-07-2011, 22:09
Батник затыкается на не правильных именах файлов, типа :
16_21217_26+PE%C3%87AS+PRONTAS.JPG.jpg
12809_Гостиная_3.jpg.jpg
12810_Штукатурка_1.jpg.jpg
12811_Штукатурка_2.jpg.jpg
Либо эти файлы (с кривыми именами) надо удалять, либо как-то переименовывать.

Задачу считаю решенной, спасибо megaloman

Iska
18-07-2011, 11:18
В принципе, у меня сработали и пакетный файл (http://forum.oszone.net/post-1714585.html#post1714585) Foreigner'а, и пакетный файл (http://forum.oszone.net/post-1714623.html#post1714623) megaloman'а.

Но только надо по одному файлу из тех, у которых размер одинаков, оставить. »
Ясно. Поскольку изначально в условиях задачи было сказано, что:
удалял одинаковые по размеру файлы в одной папке »
то, я хоть и удивился, но сделал именно так, как было сказано :). Причём, коллега megaloman оказался проницательнее — не только удивился, но и усомнился (и, как выяснилось, оказался прав).

Тогда ещё проще (хоть уже и нет необходимости, но приведу код):
Option Explicit

Dim objFSO
Dim strFolder
Dim objFile
Dim objDictionary
Dim elem


If WScript.Arguments.Count = 1 Then
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

strFolder = WScript.Arguments.Item(0)

If objFSO.FolderExists(strFolder) Then
Set objDictionary = WScript.CreateObject("Scripting.Dictionary")

For Each objFile In objFSO.GetFolder(strFolder).Files
If objDictionary.Exists(objFile.Size) Then
objFSO.DeleteFile objFile.Path, True
Else
objDictionary.Add objFile.Size, objFile.Path
End If
Next

objDictionary.RemoveAll

Set objDictionary = Nothing
Else
WScript.Echo "Folder [" & strFolder & "] not found."
End If

Set objFSO = Nothing
Else
WScript.Echo "Usage: " & WScript.ScriptName & " <folder>"
End If

WScript.Quit 0
и примерно так (уверен, что подобрал не самый оптимальный вариант):
param (
[string]$Folder = "E:\Песочница\0061\*"
)
Get-ChildItem -Path $Folder | `
Where-Object -FilterScript { -not $_.PSIsContainer } | `
Group-Object -Property Length | `
Where-Object -FilterScript { $_.Count -gt 1 } | `
ForEach-Object -Process {
$_.Group | Select-Object -Skip 1 | Remove-Item -Force
}




© OSzone.net 2001-2012