Групповая модификация времени изменения с помощью счётчика

Обсуждение вопросов автоматизации Total Commander с помощью сторонних программ и скриптовых технологий.

Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер

Ответить
Аватара пользователя
Olaf
Сообщения: 11
Зарегистрирован: Чт мар 23, 2006 17:42

Групповая модификация времени изменения с помощью счётчика

Сообщение Olaf »

У меня есть группа файлов, время последнего изменения которых мне нужно модифицировать так, чтобы оно различалось на минуту (к примеру:
файл001 - время последнего изменения 00:00,
файл002 - время последнего изменения 00:01 и так далее).
Я знаю, что при групповом переименовании файлов можно использовать счётчик.
А нельзя ли его использовать в данной ситуации?
Аватара пользователя
Batya
Сообщения: 2236
Зарегистрирован: Ср дек 15, 2004 09:51
Откуда: Москва, Россия

Сообщение Batya »

Olaf
Попробуй ReDate Addon.
Нет, я не сплю. Я просто медленно моргаю.
Аватара пользователя
Flasher
Сообщения: 14229
Зарегистрирован: Пт ноя 06, 2009 00:33
Откуда: Москва

Сообщение Flasher »

Можно попробовать:

Код: Выделить всё

'=================================================================
' Заменить время модификации выбранных файлов с учётом счётчика
' на конце их имён по шаблону: <имя файла>№  >> <час>:<мин: № - 1>

' Параметр: %WL
'=================================================================
If WScript.Arguments.Count = 0 Then WScript.Quit
Set Shell = CreateObject("Shell.Application")
With CreateObject("Scripting.FileSystemObject")
  For Each F in Split(.GetFile(WScript.Arguments(0)).OpenAsTextStream(1, -1).ReadAll, vbNewLine)
    If F <> "" Then 
      If .FileExists(F) Then
        BN = .GetBaseName(F) : Rev = StrReverse(BN)
        Set Fd = Shell.NameSpace(.GetParentFolderName(F))
        Set Fl = Fd.ParseName(.GetFileName(F))        
        For i = 1 To Len(BN)
          If Not IsNumeric(Mid(Rev, i, 1)) Then Exit For
        Next
        If i > 1 Then
          o = Right(BN, i - 1) : m = Fix(o) - 1
          If m > 59 Then h = Fix(m/60) : m = m-h*60 : End If
          If m < 10 Then m = "0" & m
          If h > 23 Then h = h - Fix(h/24)*24
          If h = 0 Then h = "00"
          If h < 12 Then HS = "AM" Else HS = "PM"
          If Len(h) = 1 And Fix(h) < 10 Then h = "0" & h
          Fl.ModifyDate = DateValue(Fl.ModifyDate) & " " & h & ":" & m & ":00 " & HS
        End If
      End If
    End if
  Next
End With
У меня почему-то DateLastModified/ModifyDate выдают разницу в час в сравнении с атрибутами, что показывает ТС и система..
Автору сборки TC Image (Andrey_A) настоятельно рекомендуется не распространять на иных ресурсах любую предоставленную мной где-либо техническую информацию по автоматизации и оптимизации в работе с ТС и системой.
Аватара пользователя
LonerD
Сообщения: 1174
Зарегистрирован: Вт янв 04, 2011 03:56
Откуда: Макеевка
Контактная информация:

Сообщение LonerD »

BulkFileChanger может такое сделать.
Поставить галочку на Date/Time sequence mode
Windows 11 | TC DreamLair eternal pre-α
Аватара пользователя
Olaf
Сообщения: 11
Зарегистрирован: Чт мар 23, 2006 17:42

Сообщение Olaf »

Спасибо!
helb
Сообщения: 57
Зарегистрирован: Ср окт 08, 2014 21:46

Сообщение helb »

Пользуюсь powershell-скриптом близким и частично пересекающимся по назначению.
Скрипт для корректировки времени модификации по возрастанию в соответствии с порядком в списке. Нужен для того, чтобы порядок по времени соответствовал смысловому порядку, и последний оставался корректным при сортировке по времени. Корректирует с шагом в секунду и только там где требуется.

Запускать командой вида “powershell <имя.ps1> <параметры>”. PS должен быть установлен (актуально только для Win XP), и должно быть разрешено выполнение скриптов (единовременная команда “Set-ExecutionPolicy RemoteSigned” в среде PS)

reorder-timestamps.ps1:

Код: Выделить всё

<#	Reorder Timestamps by helb
	Adjusts timestamps of listed items to reflect list order from oldest to newest
	Корректирует время модификации указанных объектов по возрастанию в соответсвии с их порядком
	Usage: “<list file (UTF-8)>”
	Total Commander parameter: %UL
#>
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

function msgBx($text, $title, $btns = 0) {
	return [System.Windows.Forms.MessageBox]::Show($text, $title, $btns)
}

function lowerThanRemaining($idx) {
	$ts = $f[$idx].time
	for ($j = $idx+1; $j -lt $f.length; $j++) {
		if ($f[$j].time -lt $ts) { return $false }
	}
	return $true
}

if ($args.length -lt 1) { msgBx "No parameters." "Error"; return }
$list = [environment]::ExpandEnvironmentVariables($args[0])

if (!(test-path -literalPath $list)) { msgBx "List file not found." "Warning"; return }
$files = get-content $list | where-object { (test-path -literalPath $_) }
if ($files.length -lt 2) { msgBx "Too few files" "Error"; return }
$f = @()
foreach ($entry in $files) {
	$file = get-item -literalPath $entry -force
	$fl = New-Object System.Object
	$fl | Add-Member -type NoteProperty -Name obj -value $file
	$fl | Add-Member -type NoteProperty -Name time -value $file.LastWriteTime
	$f = $f + $fl
}

do {
	$cnt = 0
	$low = $prevstamp = $f[0].time
	for ($i = 1; $i -lt $f.length - 1; $i++) {
		if ($f[$i].time -le $prevstamp) {
			$prevstamp = $prevstamp.AddSeconds(1)
			$f[$i].time = $prevstamp
			$cnt++
		}
		elseif ($f[$i].time -gt $f[$i+1].time) {
			if ($f[$i+1].time.AddSeconds(-1) -gt $prevstamp) {
				$prevstamp = $f[$i+1].time.AddSeconds(-1)
				$f[$i].time = $prevstamp
			}
			else {
				if ($f[$i+1].time.AddSeconds(-1) -le $low) { $prevstamp = $low.AddSeconds(1) }
				else { $prevstamp = $f[$i+1].time.AddSeconds(-1) }
				$f[$i].time = $prevstamp
			}
			$cnt++
		}
		else {$prevstamp = $f[$i].time}
		if ($cnt -eq 0) {
			if (lowerThanRemaining $i) { $low = $prevstamp }
		}
	}
	if ($f[$i].time -le $prevstamp) {
		$prevstamp = $prevstamp.AddSeconds(1)
		$f[$i].time = $prevstamp
		$cnt++
	}
} while ($cnt -gt 0)
foreach ($fl in $f) {
	$fl.obj.LastWriteTime = $fl.time
}
helb
Сообщения: 57
Зарегистрирован: Ср окт 08, 2014 21:46

Сообщение helb »

Пара фиксов и индикация неудачных попыток.

reoder-timestamps.ps1:

Код: Выделить всё

<#	Reorder Timestamps [by helb] v2015-11-08
	Adjusts timestamps of listed items to reflect list order from oldest to newest
	Корректирует время модификации указанных объектов по возрастанию в соответсвии с их порядком 
	Usage: “<list file (UTF-8)>”
	Total Commander list parameter: %UL
#>
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

function msgBx($text, $title, $btns = 0) {
	return [System.Windows.Forms.MessageBox]::Show($text, $title, $btns)
}

function lowerThanRemaining($idx) {
	$ts = $f[$idx].time
	for ($j = $idx+1; $j -lt $f.length; $j++) {
		if ($f[$j].time -lt $ts) { return $false }
	}
	return $true
}

function setTimestamp($path, $time) {
    $file = get-item -LiteralPath $path -force
    $ro = $file.IsReadOnly
    $file.IsReadOnly = $false
    $file.LastWriteTime = $time
    if ($ro) { $file.IsReadOnly = $true }
}

if ($args.length -lt 1) { msgBx "No parameters." "Error"; return }
$list = [environment]::ExpandEnvironmentVariables($args[0])

if (!(test-path -literalPath $list)) { msgBx "List file not found." "Warning"; return }
[array]$files = get-content $list | where-object { (test-path -literalPath $_) }
if ($files.length -lt 2) { msgBx "Too few files" "Error"; return }
$f = @()
foreach ($entry in $files) {
	$file = get-item -literalPath $entry -force
	$fl = new-object System.Object
	$fl | add-member -type NoteProperty -name obj -value $file
	$fl | add-member -type NoteProperty -name time -value $file.LastWriteTime
	$f = $f + $fl
}

do {
	$cnt = 0
	$low = $prevstamp = $f[0].time
	for ($i = 1; $i -lt $f.length - 1; $i++) {
		if ($f[$i].time -le $prevstamp) {
			$prevstamp = $prevstamp.AddSeconds(1)
			$f[$i].time = $prevstamp
			$cnt++
		}
		elseif ($f[$i].time -gt $f[$i+1].time) {
			if ($f[$i+1].time.AddSeconds(-1) -gt $prevstamp) {
				$prevstamp = $f[$i+1].time.AddSeconds(-1)
				$f[$i].time = $prevstamp
			}
			else {
				if ($f[$i+1].time.AddSeconds(-1) -le $low) { $prevstamp = $low.AddSeconds(1) }
				else { $prevstamp = $f[$i+1].time.AddSeconds(-1) }
				$f[$i].time = $prevstamp
			}
			$cnt++
		}
		else {$prevstamp = $f[$i].time}
		if ($cnt -eq 0) {
			if (lowerThanRemaining $i) { $low = $prevstamp }
		}
	}
	if ($f[$i].time -le $prevstamp) {
		$prevstamp = $prevstamp.AddSeconds(1)
		$f[$i].time = $prevstamp
		$cnt++
	}
} while ($cnt -gt 0)
$errs = 0
foreach ($fl in $f) {
try{
    setTimestamp $fl.obj $fl.time
} catch {
    $errs++
}
}
if ($errs) { MsgBx("Failed setting timestamp on "+ $errs + "/" + $f.length) }
Ответить