Войти

Показать полную графическую версию : удаление файлов по списку list.txt


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

Busla
11-08-2018, 12:16
YuS_2, поиск индекса по значению в общем случае плохая затея: неэффективная и нужно быть уверенным в уникальности значений
да и вообще ненужная: кто сказал, что группировать можно только по свойствам объекта?

$oCount = @{ iValue = 0 }
$iLimit = 8

Get-ChildItem *.jpg | Group-Object { [Math]::DivRem($oCount.iValue++ , $iLimit, [ref]$null) }

единственное - потребовался небольшой хак, чтобы итератор стал ссылочным типом

Iska, Double - это двоичная дробь и двоичный сдвиг, поэтому отбрасывание дробной части может дать неожиданный результат.

Iska
11-08-2018, 22:21
а зачем?! »
Мне — для группировки файлов «пачками».

По коду (http://forum.oszone.net/post-2825837.html#post2825837): с этим-то понятно. Минус такого подхода — в двойной проверке: общий цикл «для всего» и вложенная в него аналогичная проверка для того же условия, либо вложенным циклом, как у Вас (и так — да, красивее), либо простым условием с прерыванием цикла, как обычно делаю я. То бишь, делать — можно, но громоздко. Ладно, когда другого выхода нет (например, в том же WSH), а тут хотелось бы использовать конвеер и группировку.

польская нотация придумана, для имитации пользовательских типов - чтобы килограммы с километрами не складывать, а не для дублирования системных »
Не-не-не, это операция приведения типа, и я повторюсь, что не вижу принципиальной разницы что использовать — псевдоним или полное определение типа, [int] или [System.Int32], [string] или [System.String].

Не понял зачем там do ... until с рандомом, да и разбираться не стал...»
Дабы получить имя временного файла, которого гарантированно не существует в указанном каталоге. Чтобы быть абсолютно точно уверенным в данном факте.

Эквивалент: »
Спасибо, ясно. Будем знать.

YuS_2, поиск индекса по значению в общем случае плохая затея: неэффективная и нужно быть уверенным в уникальности значений »
Ну, значения-то у нас будут уникальные (в данном случае), а вот что поиск индекса по значению в массиве есть операция крайне медлительная — это факт.

да и вообще ненужная: кто сказал, что группировать можно только по свойствам объекта? »
Busla, браво! Мысленно снимаю шляпу. Казалось бы, элементарная вещь — но ведь до этого нужно ещё дойти, сообразить, что так — передавать по конвееру одно, а группировать по другой сущности, совсем не связанной с переданным по конвееру — тоже можно.

единственное - потребовался небольшой хак, чтобы итератор стал ссылочным типом »
Вот-вот. А я на этом упёрся и фсё, не сообразил, как сделать так, чтобы и овцы были целы, и волки сыты :(. Это вовсе не хак, это вполне нормальный способ обойти ограничения передачи аргумента по значению.

Iska, Double - это двоичная дробь и двоичный сдвиг, поэтому отбрасывание дробной части может дать неожиданный результат. »
Ну, тут по-хорошему надо смотреть, как хранятся числа в памяти — с фиксированной точкой или плавающей, как именно организовано вычисление операции деления. Совсем не копался на эту тему. Почему использовал Floor() — потому что не обнаружил в PowerShell оператора целочисленного деления, а DivRem() — тупо не нашёл :lol:.

bidjo
11-08-2018, 23:38
эмм простите , а итоговый то скрипт какой?:)

Iska
11-08-2018, 23:41
а итоговый то скрипт какой? »
А итоговый — пишется по новым данным :lol:. Потом туда добавится и это:
выходное имя видео это то, что я задам, можно даже указать время сегодняшнее.
а нельзя ли, в качестве имени файла указать первую строчку и последнюю строчку list.txt?
допустим в папке лежат фото собачей будкии, а на выходе получилось не N.avi, а Будка злой собаки 01-01-2018_00h01m01s Будка злой собаки 01-01-2018_23h59m01s.avi »

Iska
12-08-2018, 02:35
Ну, вот, как-то так:
Param (
[System.String]$Path2FFMpeg = "$($ENV:ProgramFiles)\FFmpeg\bin\ffmpeg.exe",
[System.String]$SourceFolder = '.',
[System.Int32]$GroupBy = 960
)

$SourceFolder = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($SourceFolder)

if([System.IO.Directory]::Exists($SourceFolder)) {
if([System.IO.File]::Exists($Path2FFMpeg)) {
do {
$sFileList = [System.IO.Path]::Combine($SourceFolder, [System.IO.Path]::GetRandomFileName())
} until(-not [System.IO.File]::Exists($sFileList))

$hTable = @{ iCount = 0 }
$aFiles = Get-ChildItem -Path "$SourceFolder\*.*" -File -Include '*.jpg', '*.jpeg', '*.jpe'

if($aFiles.Count -gt 0) {
$bSuccess = $true

$aFiles | Group-Object { [Math]::DivRem($hTable.iValue++ , $GroupBy, [ref]$null) } | ForEach-Object -Process {
$_.Group | ForEach-Object -Begin {
$sContent = ''
} -Process {
$sContent += "file '$($_.Name)'`r`n"
} -End {
$sOutputFileName = ($_.Group[0]).BaseName + ' - ' + ($_.Group[$_.Group.Count - 1]).BaseName + ".avi"

Out-File -InputObject $sContent -FilePath $sFileList -Encoding "Default" -NoNewline

$oCurrentCodePageEncoding = [Console]::OutputEncoding
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

$oProcess = Start-Process `
-FilePath $Path2FFMpeg `
-ArgumentList "-y -f concat -safe 0 -r 2 -i `"$([System.IO.Path]::GetFileName($sFileList))`" -threads 2 -vcodec libx264 -preset veryfast -qp 30 -tune grain -r 1 -framerate 1 `"$sOutputFileName`"" `
-WorkingDirectory $SourceFolder `
-NoNewWindow -Wait -PassThru

[Console]::OutputEncoding = $oCurrentCodePageEncoding

if($oProcess.ExitCode -eq 0) {
Write-Host "`r`n$($_.Count) file(s) splitted into [$sOutputFileName].`r`n" -ForegroundColor Green
} else {
$bSuccess = $false
Write-Host "`r`nProbably an error [$($oProcess.ExitCode)] occured while try split files into [$sOutputFileName].`r`n" -ForegroundColor Red
}
}
}

[System.IO.File]::Delete($sFileList)

if($bSuccess) {
switch($host.UI.PromptForChoice("Delete files?", "Delete all splitted jpeg files?", [System.Management.Automation.Host.ChoiceDescription[]] @("&Yes", "&No"), 1)) {
0 {
foreach($oFile in $aFiles) {
$oFile.Delete()
Write-Host "File [$($oFile.Name)] deleted." -ForegroundColor Green
}
Write-Host "`r`nTotal $($aFiles.Count) file(s) deleted." -ForegroundColor Green
}
1 {
# Nothing to do
}
}
}
} else {
Write-Host "Can't find any jpeg files in source folder [$SourceFolder], nothing to do." -ForegroundColor Green
}
} else {
Write-Host "Can't find ffmpeg in [$Path2FFMpeg]." -ForegroundColor Red
}
} else {
Write-Host "Can't find source folder [$SourceFolder]." -ForegroundColor Red
}
Теперь первый параметр, Path2FFMpeg — путь к ffmpeg.exe (по умолчанию — C:\Program Files\FFmpeg\bin\ffmpeg.exe), второй параметр, SourceFolder — путь к целевому каталогу (по умолчанию — текущий каталог), третий параметр, GroupBy — число файлов в «пачке», из которой формируется видеофайл (по умолчанию — 960). Имена выходных видеофайлов формируются по указанному Вами принципу, нумерацию я оттуда вообще убрал.

Например, вызываем скрипт для обработки каталога 0008, находящегося в текущем каталоге, с группировкой файлов по двадцать штук:
https://i.imgur.com/o2ENkU5.png
https://i.imgur.com/KRZnjho.png

YuS_2
12-08-2018, 09:22
неэффективная и нужно быть уверенным в уникальности значений»
это да... но если очень хочется, почему бы и нет? В смысле, что вариант использования, вполне присутствует. :)
А на счет уникальности - в данном, конкретном случае, всё на месте, в смысле уверенность в этом есть.

кто сказал, что группировать можно только по свойствам объекта? »
Вот! А это, как раз, пример творческого подхода. Вполне себе, ещё вариант и более быстродействующий...

Дабы получить имя временного файла, которого гарантированно не существует в указанном каталоге. Чтобы быть абсолютно точно уверенным в данном факте. »
Угу, сама идея-то понятна, непонятно с какой целью используется... ну, да это вообще не важно...

не вижу принципиальной разницы что использовать »
Это точно. Просто алиасы, как правило, короче в записи и поэтому удобнее использовать их, а разницы нет абсолютно.

потому что не обнаружил в PowerShell оператора целочисленного деления, а DivRem() — тупо не нашёл »
А мне вот powershell чем понравился... у него, всегда можно, не рыская по справочникам, дернуть встроенную справку...
man about_Arithmetic_Operators -full
- там, конечно, всего не найти, но очень многое, можно в памяти и не держать:
[int](5/2)

и так тоже можно:
[math]|gm -stat
имхо, это ведь очень удобно...

Iska
12-08-2018, 12:12
Угу, сама идея-то понятна, непонятно с какой целью используется... ну, да это вообще не важно... »
Ну, как «зачем» — чтобы гарантировать, что данное полученное имя временного файла не совпадает с уже существующим. Да, вероятность совпадения имён теоретически околонулевая, но всё ж не нулевая.

А мне вот powershell чем понравился... у него, всегда можно, не рыская по справочникам, дернуть встроенную справку... »
А мне именно тем же — не понравился абсолютно: убого, неточно и недостаточно.

Busla
12-08-2018, 14:25
там, конечно, всего не найти, но очень многое, можно в памяти и не держать:
[int](5/2) »
вот и попробуйте сделать:
[int](7/2)

к сожалению, совершенно неочевидна принадлежность к библиотеке Math
[math]|gm -stat »
Это чисто декоративная обёртка надо базовыми операциями

не вижу принципиальной разницы что использовать — псевдоним или полное определение типа, [int] или [System.Int32], [string] или [System.String] »
тот, кто понимает, пытается в каждом обращении к "низкоуровневым" библиотекам бэкэнда усмотреть подвох: почему именно Int32? - что завязано на конкретную разрядность? Или при вызове функций - что не так в реализации стандартного решения?
а тот, кто совсем не знаком с .NET не всегда поймёт что написано

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

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

Iska, поделитесь, пожалуйста: как вы сделали длинный скриншот консоли?

YuS_2
12-08-2018, 15:23
вот и попробуйте сделать »
а что не так? Нормальное округление :)
Причем, округление банкиров (http://msdn.microsoft.com/en-us/library/system.midpointrounding.aspx).
Так сказать:
[int]3.5 -eq [int]4.5

к сожалению, совершенно неочевидна принадлежность к библиотеке Math »
Отчего же? [int] - алиас [System.Int32]
Или Вы о чем?

Это чисто декоративная обёртка надо базовыми операциями »
Так ведь, что такое powershell, по сути? :)

Busla
12-08-2018, 15:47
а что не так? Нормальное округление »
1) в других языках приведение float к int работает как floor
2) в данном контексте нарезка будет не на равные части, а ±1

Или Вы о чем? »
о том, что странно искать целочисленное деление в библиотеке Math

Iska
12-08-2018, 16:48
вот и попробуйте сделать:
[int](7/2)
к сожалению, совершенно неочевидна принадлежность к библиотеке Math »
То бишь, получается, я был неправ, и на самом деле работает подобное:
value, rounded to the nearest 32-bit signed integer. If value is halfway between two whole numbers, the even number is returned; that is, 4.5 is converted to 4, and 5.5 is converted to 6.
https://i.imgur.com/j9FShjE.png

Сказка, просто сказка.

Или при вызове функций - что не так в реализации стандартного решения? »
Я лично охреневал от того, что в куче командлетов для вывода в файл тупо отсутствовала часть кодировок (потом, с течением времени, немного стали добавлять), реализация сего делалась разными параметрами. Ужас. Что мешало тупо использовать параметр типа [System.Text.Encoding] вместо набора строк?! И по сю пору (если в шестой версии не поменялось, не смотрел) — хочешь манипулировать наличием/отсутствием BOM и видом концов строк — забудь про командлеты, пользуй функции .Net.

а тот, кто совсем не знаком с .NET не всегда поймёт что написано »
«Нэ вэрю!» Без .Net на гольном PowerShell'е далеко не уедешь, шаг влево, шаг вправо — и приехали. Да и просто даже для того, чтобы мало-мальски представлять, как это вообще работает, нужен .Net.

Iska, как вы сделали длинный скриншот консоли? »
ShareX (ShareX - Screen capture, file sharing and productivity tool (https://getsharex.com/)), из меню в трее — \Захват\Захват с прокруткой…, выбрать внутреннюю часть окна консоли PowerShell (так, чтобы ползунок прокрутки буфера экрана консоли оставался за пределами выбранного), «Начать захват», дождаться конца прокрутки и захвата, «Загрузить/сохранить в соответствии с настройками задач после захвата, скадрировать (обрезать) изображение, появившееся в редакторе. Если предварительно уменьшить для текущего окна консоли размер буфера экрана так, чтобы всё вмещалось и не было ничего лишнего — можно обойтись и без обрезания.

Удобная штука. Я перешёл на ShareX с PicPick.

о том, что странно искать целочисленное деление в библиотеке Math »
А если не в Math — то где :unsure:?!

YuS_2
12-08-2018, 18:04
1) в других языках приведение float к int работает как floor
2) в данном контексте нарезка будет не на равные части, а ±1 »
1. Дык, а зачем на них ориентироваться? да и при чем тут powershell, если это дотнет...
"Windows PowerShell автоматически выбирает числовой тип платформы .NET"
2. Это да и именно поэтому Ваш вариант [math]::divrem, наиболее красивый... имхо

о том, что странно искать целочисленное деление в библиотеке Math »
Всё равно не понял. Искать можно где угодно, если оно есть и его можно использовать...
В powershell, например, оно есть, а вот использовать возвращаемый остаток, в данном случае неприемлемо... т.е. поискать его надо в более других доступных местах, да хоть в [math]::truncate - почему нет?

YuS_2
12-08-2018, 18:24
Без .Net на гольном PowerShell'е далеко не уедешь, шаг влево, шаг вправо — и приехали. Да и просто даже для того, чтобы мало-мальски представлять, как это вообще работает, нужен .Net. »
Конечно, нужен, а без .net powershell будет калекой... да и многие командлеты построены на нем.




© OSzone.net 2001-2012