Was gibt es Neues?

Hier ist nicht die zweideutige Kabarettisten-Runde am Freitagabend in ORF-1 gemeint, sondern die gleichnamige Sendung von Heinz Conrads, der seinen Wochenrückblick ziemlich wertfrei und unpolitisch jeden Sonntag an die „Madln und Buam“ sandte. Und auch dieser Zusammenhang ist nur aus werbetechnischen Gründen gewählt worden, um ein hübsches Titelbild zum trockenen Thema zu haben. Es geht darum, wie man im Cloud-Speicher Neuigkeiten bekannt geben kann.

„Was gibt es Neues“ wurde zwischen 1946 und 1986 gesendet.

Große Datensammlungen

Viele Computer-User haben mehr oder weniger große Datensammlungen, die von Zeit zu Zeit vergrößern werden. ClubComputer verwaltet seine Sammlung im Ordner clubintern auf dem cc|drive (https://drive.ccc.at). Michael hat sich diese Datensammlung angeschaut und hat sich gefragt, was sich denn seit seinem letzten Besuch verändert hat.

Die Frage ist daher: „Was gibt es Neues im Ordner clubintern?

Das ist eine einfach zu beantwortende Frage, wenn man direkten Zugriff auf die Daten hat, denn ein einfaches Skript in PHP oder ASP könnte uns sagen, welche Dateien zuletzt auf den Server kopiert worden sind. clubintern liegt aber auf einem Cloudspeicher, der den Usern keine Programmiersprache zur Verfügung stellt.

Daher wurden eigene Inhaltsverzeichnisse angelegt, die die Suche im Datendschungel auf dem Cloud-Speicher erleichtern.

Hier werden diese Inhaltsverzeichnisse von clubintern und danach auch deren Herstellung beschrieben.

Inhaltsverzeichnis von clubintern

Neben einem Gesamtverzeichnis gibt es auch Verzeichnisse der jährlichen Neuigkeiten und ab 2022 auch die monatlichen Neueintragungen. Fehlt ein Monat oder ein Jahr, gab es in diesem Jahr keine Neuigkeiten. Die Dateien werden aktualisiert, wenn neue Inhalte in das Verzeichnis kopiert worden sind.

Es gibt ein Verzeichnis des kompletten Ordners clubintern und auch ein zweites im Ordner clubintern/buecher.

Verzeichnis des Ordners clubintern

10.01.2022     07:57    73840   2013 inhalt-neu.txt     Neuigkeiten 2013
10.01.2022     07:57      759   2014 inhalt-neu.txt     Neuigkeiten 2014
10.01.2022     07:57      429   2016 inhalt-neu.txt     Neuigkeiten 2016 
10.01.2022     07:57  1692377   2017 inhalt-neu.txt     Neuigkeiten 2017
08.01.2022     15:38   508351   2019 inhalt-neu.txt     Neuigkeiten 2019
08.01.2022     15:38    61939   2020 inhalt-neu.txt     Neuigkeiten 2020
08.01.2022     15:38  2277720   2021 inhalt-neu.txt     Neuigkeiten 2021
10.01.2022     07:57   128518   2022 inhalt-neu.txt     Neuigkeiten 2022
08.01.2022     15:38    96937   2022-01 inhalt-neu.txt  Neuigkeiten 2022 Jänner
10.01.2022     07:57  3696612   inhalt-gesamt.txt       Gesamtverzeichnis

Verzeichnis des Ordners clubintern/buecher

10.01.2022     07:21      846   2013 inhalt-neu.txt     Neuigkeiten 2013
10.01.2022     07:21      389   2016 inhalt-neu.txt     Neuigkeiten 2016
10.01.2022     07:21  1610049   2017 inhalt-neu.txt     Neuigkeiten 2017
10.01.2022     07:21    23935   2018 inhalt-neu.txt     Neuigkeiten 2018
10.01.2022     07:21     6441   2019 inhalt-neu.txt     Neuigkeiten 2019
10.01.2022     07:21    18445   2020 inhalt-neu.txt     Neuigkeiten 2020
10.01.2022     07:21    34641   2021 inhalt-neu.txt     Neuigkeiten 2021
10.01.2022     07:38    16041   2022 inhalt-neu.txt     Neuigkeiten 2022
10.01.2022     07:21    16526   2022-01 inhalt-neu.txt  Neuigkeiten 2022 Jänner
10.01.2022     07:38  1676808   inhalt-gesamt.txt       Gesamtverzeichnis

Diese Dateien werden durch Aufruf des Skripts clubintern-update.ps1 automatisch aktualisiert.

Im cc|drive öffnet man den Ordner clubintern und sortiert die Dateien absteigen. Dann ist das Gesamtinhaltsverzeichnis die erste Datei inhalt-gesamt.txt und danach folgt die Datei der Neuerungen im letzten Monat, in dem Neues eingetragen wurde, hier 2022-01 inhalt-neu.txt.

cc|drive -> clubintern -> Dateien absteigend sortieren

Herstellung des Inhaltsverzeichnisses

PowerShell bietet sich für solche Aufgaben an. In der Folge werden zuerst alle Details vorgestellt und danach das fertige Programm. Die Frage an Google lautet: sort files using creation date recursive powershell

Bei den vielen Antworten bevorzuge ich die Seite von stackoverflow.com:
https://stackoverflow.com/questions/40904836/how-to-get-n-files-in-a-directory-order-by-last-modified-date/40904876

Dateien und Ordner anzeigen

Get-ChildItem 'D:\Temp'                    # Dateien und Ordner anzeigen
Get-ChildItem 'D:\Temp' -Directory         # Ordner anzeigen 
Get-ChildItem 'D:\Temp' -File              # Dateien anzeigen
Get-ChildItem 'D:\Temp' -File -Recurse     # Dateien auch in allen Unterverzeichnissen anzeigen
Get-ChildItem 'D:\Temp' -Include '*.epub'  # Nur .epub-Dateien berücksichtigen

Sortieren

... | Sort-Object LastWriteTime              # Aufsteigend sortieren
... | Sort-Object LastWriteTime -Descendung  # Absteigend sortieren

Einschränkungen

... | Select-Object -First 10                # Nur die ersten Änderungen anzeigen
... | Select-Object -Last 10                 # Nur die letzten Änderungen anzeigen

Welches Datum?

In den Attributen finden sich mehrere Zeitangaben, nach denen sortieren werden könnte, aber welche? PowerSehll kann uns das sagen:

Get-ChildItem -File | Get-Member -MemberType Property | Where-Object -Property Definition -Like "datetime*"
TypeName: System.IO.FileInfo
Name              MemberType Definition
----              ---------- ----------
CreationTime      Property   datetime CreationTime {get;set;}
CreationTimeUtc   Property   datetime CreationTimeUtc {get;set;}
LastAccessTime    Property   datetime LastAccessTime {get;set;}
LastAccessTimeUtc Property   datetime LastAccessTimeUtc {get;set;}
LastWriteTime     Property   datetime LastWriteTime {get;set;}
LastWriteTimeUtc  Property   datetime LastWriteTimeUtc {get;set;}

Änderungen seit

Um einen bestimmten Zeitbereich einzuschränken, findet sich hier ein geeigneter Befehl:
https://stackoverflow.com/questions/30865911/get-list-of-files-whose-creation-date-is-greater-than-some-date-time

... | Where-Object { $_.CreationTime -gt [datetime]"2021/12/31"         # Variante 1
... | Where-Object CreationTime -gt ([DateTime]::Parse('2021/12/31'))   # Variante 2

Alle Änderungen 2021

Erweitert man nun um ein Anfangs- und Endedatum erhält man alle Änderungen des letzten Jahres

... | Where-Object CreationTime -ge ([DateTime]::Parse('2021/01/01')) 
    | Where-Object CreationTime -le ([DateTime]::Parse('2021/12/31'))

Ausgabeformat

Das übliche Ausgabeformat enthält die Attribute, den Datumsstempel, die Länge und den Namen der Datei oder des Verzeichnisses. Man kann die Spalten aber auch einschränken, um eine übersichtlichere Darstellung zu erhalten:

... | Format-Table Name, CreationTime

Update

Fassen wir alles zusammen: Alle Dateien rekursiv öffnen, deren Erstellzeitpunkt nach dem 1. Jänner und vor dem 31. Dezember liegt. Ausgabe des Namens des Verzeichnisses und des Titels der Datei.

Get-ChildItem "S:\onedrive\bücher" -Recurse -File 
  | Where-Object CreationTime -ge ([DateTime]::Parse('2022/01/01')) 
  | Where-Object CreationTime -le ([DateTime]::Parse('2022/12/31')) 
  | Format-Table @{Name="URLPath";Expression=  
      {$($_.Directory.FullName.Replace("S:\onedrive\bücher\",""))}}, Name

clubintern-update.ps1

Das vollständige Programm sieht man hier.

# Was gibt es Neues in clubintern?
#
Clear-Host
$FileName = "inhalt"

function Inhaltsverzeichnis 
{
  Param ([string] $Pfad)

  $CurrentDate = Get-Date -UFormat "%Y/%m/%d"
  $CurrentYear = [int]$CurrentDate.Substring(0,4)
  $CurrentMonth = [int]$CurrentDate.Substring(5,2)
  $CurrentFileDate = $CurrentDate.Replace("/","-")

  # Gesamtverzeichnis
  
  $OutputFileName = $Pfad + $FileName + "-gesamt.txt"
  
  Get-ChildItem $Pfad -Recurse `
    | Format-Table @{Name="URLPath";Expression={$($_.Directory.FullName.Replace("$Pfad","") )}}, Name `
    | Out-File $OutputFileName
  Write-Host "+g " -NoNewLine
      
  # Jahrgangsweise Neuerscheinungen
  
  $y = 0;
  for ($y=2010; $y -le $CurrentYear; $y++) {
      $OutputFileName = $Pfad + $y + " " + $FileName + "-neu.txt"
      if ([System.IO.File]::Exists($OutputFileName) -and ($y -ne $CurrentYear)) {
        Write-Host "-y" -NoNewLine
      } else {
        Get-ChildItem $Pfad -Recurse -File `
          | Where-Object CreationTime -ge ([DateTime]::Parse("$y/01/01")) `
          | Where-Object CreationTime -le ([DateTime]::Parse("$y/12/31")) `
          | Format-Table @{Name="Kapitel";Expression={$($_.Directory.FullName.Replace($Pfad,"") )}}, Name  `
          | Out-File $OutputFileName 
        Write-Host "+y" -NoNewLine
      }
      if ((Get-Item $OutputFileName).length -eq 0) {
        Remove-Item $OutputFileName
      }
  }
  Write-Host " " -NoNewLine
  
  # Monatsweise Neuerscheinungen des laufenden Jahres
  
  for ($m=1; $m -le $CurrentMonth; $m++) {
    $OutputFileName = $Pfad + $CurrentYear + "-" + ([string]$m).PadLeft(2,'0') + " " + $FileName + "-neu.txt"
    if ([System.IO.File]::Exists($OutputFileName) -and ($y -ne $CurrentMonth)) {
      Write-Host "-m" -NoNewLine
    } else {
      Get-ChildItem $Pfad -Recurse -File `
        | Where-Object CreationTime -ge ([DateTime]::Parse([string]$CurrentYear+"/"+([string]$m).PadLeft(2,'0') + "/" + "01")) `
        | Where-Object CreationTime -lt ([DateTime]::Parse([string]$CurrentYear+"/"+([string]($m+1)).PadLeft(2,'0') + "/" + "01")) `
        | Format-Table @{Name="Kapitel";Expression={$($_.Directory.FullName.Replace($Pfad,"") )}}, Name  `
        | Out-File $OutputFileName 
      Write-Host "+m" -NoNewLine
    }
    if ((Get-Item $OutputFileName).length -eq 0) {
      Remove-Item $OutputFileName
    }
  }
  Write-Host " $Pfad" 
}

Inhaltsverzeichnis   "S:\onedrive\bücher\"
Inhaltsverzeichnis   "S:\OwnCloud_root\clubintern\"
Inhaltsverzeichnis   "S:\OwnCloud_root\clubintern\buecher\"

Die Funktion Inhaltverzeichnis wird auf drei Pfade angewendet.

Geändertes Erstelldatum

Im Zuge des Anlegens der Datensammlung clubintern wurden die Daten von verschiedensten Quellen zusammengetragen und dann auf einem gemeinsamen Ort gespeichert. Alles ist zur Sicherheit doppelt gespeichert und in der Cloud repliziert.

Wendet man nun das Programm zur Herstellung der Inhaltsverzeichnisse an, orientiert sich das Programm am Erstellungszeitpunk (CreationTime). Aber leider ändert sich dieser Zeitpunkt beim Kopieren, Normalerweise ist das kein Problem, doch wenn man alle Daten zu einem bestimmten Datum auf ein neues Laufwerk kopiert, ist das Erstellzeitpunkt (CreationTime) für alle Dateien gleich eingestellt worden. Das bedeutet, dass eine Herstellung der Inhaltsverzeichnisse am ursprünglichen Laufwerk ein ganz anderes ist. Am neuen Laufwerk gibt es Änderungen nur im Jahr des Kopierzeitpunkts, am ursprünglichen Laufwerk aber sind diese Neuzugänge auf mehrere früheren Jahre verteilt.

Es wäre hübsch, wenn der Erstellzeitpunkt an allen Speicherorten derselbe wäre!

Man kann alle Dateien am ursprünglichen Speicherort rekursiv aufrufen und den Erstellzeitpunkt der ursprünglichen Datei auf die Datei am neuen Speicherort übertragen.

datensammlung-update.ps1

# Korrigieren des Erstellzeitpunkts am neuen Speicherort

Clear-Host
$Pfad_alt = "S:\OneDrive\Bücher\"
$Pfad_neu = "S:\OwnCloud_root\clubintern\buecher\"

function ChangeCreationTime {
  Param ([string] $Pfad)
  $s = Get-ChildItem $Pfad -File -Recurse  
  foreach ($obj in $s) {
    $Pfad_1 = $obj.FullName.Replace($Pfad_alt,$Pfad_neu)
    if ( [string]$obj.CreationTime -ne [string](Get-Item ($Pfad_1)).CreationTime ) {
      $line = [string]$obj.CreationTime + " " + [string](Get-Item $Pfad_1).CreationTime + " "
      Get-Item ($Pfad_1) | % {$_.CreationTime = $obj.CreationTime}
      $line += [string](Get-Item $Pfad_1).CreationTime + " " + $obj.Name
      Write-Host $line
    }
  }
}
ChangeCreationTime $Pfad_alt

Links

Zur Werkzeugleiste springen