|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » Любой язык - [решено] Удалить последний байт в файле |
|
|
Любой язык - [решено] Удалить последний байт в файле
|
Пользователь Сообщения: 93 |
Профиль | Отправить PM | Цитировать
Прошу помощи в написании скрипта который позволил бы удалить (отрезать) последний байт в файле.
Немного объясню.. есть у меня группа JPEG файлов (порядка полтысячи) у которых по непонятной мне причине в конец дописан символ перевода строки А0. В принципе с этим жить можно, но вот при поиске дубликатов из-за этой разницы получаю не тот результат на который рассчитывал. Использовать утилиты проверяющие по содержимому (т.е. более долго) пока не хочется, проще у найденных вырезать "лишний" байт в конце. Очень прошу помочь со скриптом. |
|
Отправлено: 19:34, 01-12-2014 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать На WSH:
Скрытый текст
Option Explicit Const adTypeBinary = 1 Const adSaveCreateOverWrite = 2 Dim strSourceFolder Dim objFile If WScript.Arguments.Count = 1 Then strSourceFolder = WScript.Arguments.Item(0) With WScript.CreateObject("Scripting.FileSystemObject") If .FolderExists(strSourceFolder) Then For Each objFile In .GetFolder(strSourceFolder).Files Select Case LCase(.GetExtensionName(objFile.Name)) Case "jpg", "jpeg", "jpe" With WScript.CreateObject("ADODB.Stream") .Type = adTypeBinary .Open .LoadFromFile objFile.Path .Position = objFile.Size - 1 If AscB(MidB(.Read(1), 1, 1)) = &H0A Then .Position = objFile.Size - 1 .SetEOS .SaveToFile objFile.Path, adSaveCreateOverWrite End If .Close End With Case Else ' Nothing to do End Select Next Else WScript.Echo "Can't find source folder [" & strSourceFolder & "]." WScript.Quit 2 End If End With Else WScript.Echo "Usage: " & WScript.ScriptName & " <Source folder>" WScript.Quit 1 End If WScript.Quit 0 Достаточно просто перетащить целевую папку на скрипт. Будут найдены все файлы в этой папке с расширениями "jpg", "jpeg", "jpe", и, если содержимым их последнего байта окажется «0x0A» — они будут урезаны по размеру на этот последний байт. Вложенные папки не обрабатываются. Резервных копий исходных файлов не делается. |
Отправлено: 06:02, 02-12-2014 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Примерный аналог на PowerShell (в качестве самообучения):
Скрытый текст
Param(
[string]$sSourceFolder = "E:\Песочница\0411"
)
if(Test-Path -Path $sSourceFolder -PathType Container) {
Get-ChildItem -Path $sSourceFolder -Recurse -Include "*.jpg", "*.jpeg", "*.jpe" |`
Where-Object -FilterScript {
-not $_.PSIsContainer
} | ForEach-Object -Process {
$oFileStream = $_.Open([System.IO.FileMode]::Open)
[void]$oFileStream.Seek(-1, [System.IO.SeekOrigin]::End)
if($oFileStream.ReadByte() -eq 0x0A) {
Write-Host "* $($_.Name)" -ForegroundColor Green
$oFileStream.SetLength($oFileStream.Position - 1)
} else {
Write-Host " $($_.Name)"
}
$oFileStream.Close()
$oFileStream.Dispose()
}
} else {
Write-Host "Can't find source folder [$sSourceFolder]." -ForegroundColor Red
}
P.S. Внезапно обнаружил, что Drag-n-Drop на «.ps1» не включён по умолчанию . |
Отправлено: 06:49, 02-12-2014 | #3 |
Пользователь Сообщения: 93
|
Профиль | Отправить PM | Цитировать Цитата Iska:
Только при перетаскивании на скрипт выбивает окно с ошибкой "There is no script file specified". На PowerShell работает нормально, но как-то не удобно каждый раз вручную менять путь в "[string]$sSourceFolder = "E:\..." P.S. Было бы очень желательно если бы скрипт запускался не перетаскиванием папки, а обычным "двойным щелчком". |
|
Отправлено: 12:46, 02-12-2014 | #4 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Цитата pzh2393:
Цитата pzh2393:
Цитата pzh2393:
|
||||
Отправлено: 13:04, 02-12-2014 | #5 |
Пользователь Сообщения: 93
|
Профиль | Отправить PM | Цитировать Спасибо Iska.
А можно ещё попросить вариант скрипта на WSH срабатывающего только для одного файла а не для всей папки? имя файла будет передаваться командой "cut.vbs %1" |
Отправлено: 14:12, 02-12-2014 | #6 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Как-то так:
Скрытый текст
Option Explicit Const adTypeBinary = 1 Const adSaveCreateOverWrite = 2 Dim strSourceFile Dim objFile If WScript.Arguments.Count = 1 Then strSourceFile = WScript.Arguments.Item(0) With WScript.CreateObject("Scripting.FileSystemObject") If .FileExists(strSourceFile) Then Set objFile = .GetFile(strSourceFile) Select Case LCase(.GetExtensionName(objFile.Name)) Case "jpg", "jpeg", "jpe" With WScript.CreateObject("ADODB.Stream") .Type = adTypeBinary .Open .LoadFromFile objFile.Path .Position = objFile.Size - 1 If AscB(MidB(.Read(1), 1, 1)) = &H0A Then .Position = objFile.Size - 1 .SetEOS .SaveToFile objFile.Path, adSaveCreateOverWrite Else WScript.Echo "Last byte of source file [" & strSourceFile & "] is not a 0x0A value." End If .Close End With Case Else WScript.Echo "Source file [" & strSourceFile & "] probably not a jpeg file." WScript.Quit 3 End Select Else WScript.Echo "Can't find source file [" & strSourceFile & "]." WScript.Quit 2 End If End With Else WScript.Echo "Usage: " & WScript.ScriptName & " <Source file>" WScript.Quit 1 End If WScript.Quit 0 Аналогично можно перетаскивать файл на скрипт. |
Отправлено: 14:27, 02-12-2014 | #7 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Из письма в PM:
Скрытый текст
Цитата pzh2393:
Именно что имеет смысл. Надо было писать именно здесь, и затем, если очень хочется, дать ссылку на новое сообщение в PM. Поскольку непосредственная работа с ByteArray в WSH не предусмотрена — наш выбор PowerShell: Скрытый текст
Param( [string]$sSourceFolder = "E:\Песочница\0411" ) if(Test-Path -Path $sSourceFolder -PathType Container) { Get-ChildItem -Path $sSourceFolder -Recurse -Include "*.jpg", "*.jpeg", "*.jpe" |` Where-Object -FilterScript { -not $_.PSIsContainer } | ForEach-Object -Process { $oFileStream = $_.Open([System.IO.FileMode]::Open) [void]$oFileStream.Seek(-2, [System.IO.SeekOrigin]::End) if($oFileStream.ReadByte() -eq 0xFF -and $oFileStream.ReadByte() -eq 0xD9) { Write-Host " $($_.Name)" } else { $bFound = $false for($i = $oFileStream.Length - 3; $i -ge 0; $i--) { [void]$oFileStream.Seek($i, [System.IO.SeekOrigin]::Begin) if($oFileStream.ReadByte() -eq 0xFF -and $oFileStream.ReadByte() -eq 0xD9) { $oFileStream.SetLength($oFileStream.Position) $bFound = $true break } } if($bFound) { Write-Host "* $($_.Name)" -ForegroundColor Green } else { Write-Host " $($_.Name)" -ForegroundColor Red } } $oFileStream.Close() $oFileStream.Dispose() } } else { Write-Host "Can't find source folder [$sSourceFolder]." -ForegroundColor Red } |
|
Отправлено: 15:14, 06-12-2014 | #8 |
Пользователь Сообщения: 93
|
Профиль | Отправить PM | Цитировать А что-то вроде этого на WSH не сработает?
Скрытый текст
Option Explicit Const adTypeBinary = 1 Const adSaveCreateOverWrite = 2 Dim strSourceFolder Dim objFile If WScript.Arguments.Count = 1 Then strSourceFolder = WScript.Arguments.Item(0) With WScript.CreateObject("Scripting.FileSystemObject") If .FolderExists(strSourceFolder) Then For Each objFile In .GetFolder(strSourceFolder).Files Select Case LCase(.GetExtensionName(objFile.Name)) Case "jpg", "jpeg", "jpe" With WScript.CreateObject("ADODB.Stream") .Type = adTypeBinary .Open .LoadFromFile objFile.Path .Position = objFile.Size - 1 If AscB(MidB(.Read(1), 1, 1)) = &HD9 Then ' Nothing to do Else .Position = objFile.Size - 1 .SetEOS .SaveToFile objFile.Path, adSaveCreateOverWrite End If .Close End With Case Else ' Nothing to do End Select Next Else WScript.Echo "Can't find source folder [" & strSourceFolder & "]." WScript.Quit 2 End If End With Else WScript.Echo "Usage: " & WScript.ScriptName & " <Source folder>" WScript.Quit 1 End If WScript.Quit 0 скриптописец конечно из меня "нулевой", но может все же имеет смысл? |
Отправлено: 15:51, 06-12-2014 | #9 |
Ветеран Сообщения: 27449
|
Профиль | Отправить PM | Цитировать Цитата pzh2393:
Скрытый текст
Option Explicit Const adTypeBinary = 1 Const adSaveCreateOverWrite = 2 Dim strSourceFolder Dim objFile Dim i If WScript.Arguments.Count = 1 Then strSourceFolder = WScript.Arguments.Item(0) With WScript.CreateObject("Scripting.FileSystemObject") If .FolderExists(strSourceFolder) Then For Each objFile In .GetFolder(strSourceFolder).Files Select Case LCase(.GetExtensionName(objFile.Name)) Case "jpg", "jpeg", "jpe" With WScript.CreateObject("ADODB.Stream") .Type = adTypeBinary .Open .LoadFromFile objFile.Path .Position = objFile.Size - 2 If AscB(MidB(.Read(1), 1, 1)) = &HFF And AscB(MidB(.Read(1), 1, 1)) = &HD9 Then ' Nothing to do Else For i = .Size - 3 To 0 Step -1 .Position = i If AscB(MidB(.Read(1), 1, 1)) = &HFF And AscB(MidB(.Read(1), 1, 1)) = &HD9 Then .SetEOS .SaveToFile objFile.Path, adSaveCreateOverWrite Exit For End If Next End If .Close End With Case Else ' Nothing to do End Select Next Else WScript.Echo "Can't find source folder [" & strSourceFolder & "]." WScript.Quit 2 End If End With Else WScript.Echo "Usage: " & WScript.ScriptName & " <Source folder>" WScript.Quit 1 End If WScript.Quit 0 |
|
Отправлено: 19:07, 06-12-2014 | #10 |
|
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
CMD/BAT - [решено] Как удалить последнюю строку в текстовом файле? | ivanxam | Скриптовые языки администрирования Windows | 35 | 18-09-2018 08:33 | |
CMD/BAT - [решено] Помогите удалить повторяющиеся строки в файле. | kolkin-alexandr | Скриптовые языки администрирования Windows | 9 | 03-11-2017 23:21 | |
CMD/BAT - [решено] Удалить пустую строку в файле .txt | denntl | Скриптовые языки администрирования Windows | 2 | 18-07-2013 11:48 | |
CMD/BAT - [решено] Удалить в текстовом файле по условию | AlexVong | Скриптовые языки администрирования Windows | 1 | 21-11-2010 11:53 | |
[решено] Изменить байт в файле по смещению. | semiono | AutoIt | 2 | 29-08-2010 22:57 |
|