2016-05-17 7 views
-1

Bitte beachten Sie den folgenden Code ein:Powershell - Extrahieren der Metadaten von Dateien und Netz sehen es

# import .NET 4.5 compression utilities 
Add-Type -As System.IO.Compression.FileSystem; 

$zipArchives = Get-ChildItem "*.zip"; 
foreach($zipArchive in $zipArchives) 
{ 
    $archivePath = $zipArchive.FullName; 


$archive = [System.IO.Compression.ZipFile]::OpenRead($archivePath); 
try 
{ 

    foreach($archiveEntry in $archive.Entries) 
    { 
     if($archiveEntry.FullName -notmatch '/$') 
     { 
      $tempFile = [System.IO.Path]::GetTempFileName(); 
      try 
      { 
       [System.IO.Compression.ZipFileExtensions]::ExtractToFile($archiveEntry, $tempFile, $true); 
       $windowsStyleArchiveEntryName = $archiveEntry.FullName.Replace('/', '\'); 

       Select-String -pattern "<dc:title>.*</dc:title>" -path (Get-ChildItem $tempFile) | Select-Object @{Name="Path";Expression={Join-Path $archivePath (Split-Path $windowsStyleArchiveEntryName -Parent)}} 
       #Select-String -pattern "<dc:title>.*</dc:title>" -path (Get-ChildItem $tempFile) | Select-Object Matches 
       #Select-String -pattern "<dc:subject>.*</dc:subject>" -path (Get-ChildItem $tempFile) | Select-Object Matches 
       #Select-String -pattern "<dc:date>.*</dc:date>" -path (Get-ChildItem $tempFile) | Select-Object Matches 
      } 
      finally 
      { 
       Remove-Item $tempFile; 
      } 
     } 
    } 
} 
finally 
{ 
    $archive.Dispose(); 
} 
} 

Es ist eine modifizierte Version des Codes, die ich im Internet gefunden und hat mir geholfen, Strings in ZIP-Dateien zu finden.

Meine Absicht ist jetzt, Metadaten aus Zip-Dateien mit diesem Code zu extrahieren.

Ich verstehe nicht, wie ich die beiden Arten von Informationen in separaten Zeilen anzeigen kann. Wenn Sie das Skript mit nur einer Select-String... Pipeline-Zeile ausführen, funktioniert der Code wie erwartet. Wenn Sie die zweite Pipelinezeile Select-String... aktivieren (auskommentieren), wird der zweite Informationstyp (der <dc:title>-Wert) nicht angezeigt und stattdessen ist eine leere Zeile.

Bitte helfen Sie mir:

1) Wie kann ich auch den Select-String | Select-Object Mechanismus dc:title Wert anzuzeigen, die ich im Code verwendet.

2) Wie kann ich Ausgang alle Daten in einem Tabellenformat, so dass die Tabelle wie folgt aussehen würde:

* ZIP Filename * DC Title * 
* zipfile01.zip * Bla Bla 01 * 
* zipfile02.zip * Bla Bla 02 * 
* zipfile03.zip * Bla Bla 03 * 

Dieses Format der Ausgabe am meisten verwendbar für mich sein würde.

Antwort

0

ich weiß, es ist nicht die Antwort, die Sie gesucht haben, sondern als vorübergehende Lösung, können Sie in der Lage sein, die beiden Befehle in eine ähnlichen

Select-String -pattern "<dc:title>.*</dc:title>" -path (Get-ChildItem $tempFile) | Select-Object Matches, @{Name="Path";Expression={Join-Path $archivePath (Split-Path $windowsStyleArchiveEntryName -Parent)}} 
+0

Danke, Anthony , aber diese Methode würde mein Problem nicht lösen. Ihre Antwort hat mich dazu gebracht zu verstehen, dass ich meine Frage aktualisieren muss. Der 1. "Select-String" mit "" wird eigentlich als eine Art eindeutiger Schlüssel für mich verwendet, weil ich weiß, dass alle Dateien dieses Tag in ihren Metadaten haben. Ich möchte den Dateinamen und die tatsächliche "" nicht an der gleichen Ausgangsleitung angeben. Der fertige Code würde viel mehr dc-Tags enthalten ("", "" usw.), und jedes Tag benötigt eine eigene Zeile. – kurkum

1

die Konsole „Ansicht“ für Pipeline-objcts zu kombinieren wird basierend auf dem ersten Objekt erstellt (die nur eine Path -Eigenschaft haben). Das zweite Objekt fehlt eine Path -Eigenschaft, weshalb Sie eine leere Zeile sehen. Wenn Sie die erste -Linie (die Path zeigt) auskommentiert hat, dann würde die zweite Linie funktionieren.

Objekte, die über die Pipeline gesendet werden, sollten die gleichen Eigenschaften aufweisen. Vermeiden Sie die Verwendung von select-object mit unterschiedlichen Eigenschaftensätzen. Beispiel:

..... 

$tempFile = [System.IO.Path]::GetTempFileName(); 
try 
{ 
    [System.IO.Compression.ZipFileExtensions]::ExtractToFile($archiveEntry, $tempFile, $true); 
    [System.IO.Compression.ZipFileExtensions]:: 
    $windowsStyleArchiveEntryName = $archiveEntry.FullName.Replace('/', '\'); 

    Select-String -pattern "<dc:title>(.*)</dc:title>" -path (Get-ChildItem $tempFile) | Select-Object @{n="Zip FileName";e={$zipArchive.Name}}, @{Name="DC Title";Expression={ $_.Matches.Groups[1].Value}} 
} 
finally 
{ 
    Remove-Item $tempFile; 
} 

..... 

Um alle Metadaten auszugeben, sollten Sie ein Objekt erstellen, das alle Werte enthält. Ex:

$tempFile = [System.IO.Path]::GetTempFileName(); 
try 
{ 
    [System.IO.Compression.ZipFileExtensions]::ExtractToFile($archiveEntry, $tempFile, $true); 
    [System.IO.Compression.ZipFileExtensions]:: 
    $windowsStyleArchiveEntryName = $archiveEntry.FullName.Replace('/', '\'); 

    #Avoid multiple reads 
    $content = Get-Content $tempFile 

    New-Object -TypeName psobject -Property @{ 
     "Zip Filename" = $zipArchive.Name 
     "DC Title" = if($content -match '<dc:title>(.*)</dc:title>') { $Matches[1] } else { $null } 
     "DC Subject" = if($content -match '<dc:subject>(.*)</dc:subject>') { $Matches[1] } else { $null } 
     "DC Date" = if($content -match '<dc:date>(.*)</dc:date>') { $Matches[1] } else { $null } 
    } 


} 
finally 
{ 
    Remove-Item $tempFile; 
} 

.... 

Ex. Ausgabe

Zip Filename DC Subject DC Title  DC Date 
------------ ---------- --------  ------- 
test.zip  Subject O M G   5/18/2016 

Wenn Sie separate Ansichten zwingen möchte wirklich (wird hässlich), dann müssen Sie er Objekte zu | Out-Default senden Sie eine neue Ansicht jedes Mal, ex zu erstellen:

Select-String -pattern "<dc:title>.*</dc:title>" -path (Get-ChildItem $tempFile) | Select-Object @{Name="Path";Expression={Join-Path $archivePath (Split-Path $windowsStyleArchiveEntryName -Parent)}} | Out-Default 
+0

Vielen Dank, Frode F. Es sieht besser aus, aber es gibt immer noch ein Problem Bei der Verwendung von '$ Matches [1]' Ich bekomme nicht den Match-Capture-Wert in der Tabelle angezeigt werden. Ich dachte, dass die Matchroutine das Muster vielleicht nicht gefunden hat, aber ich bin mir sicher, dass es, als ich '$ Matches [1] 'zu' $ Matches [0] '' änderte, den "/" Wert in der Spalte bekam für jede Datei, die tatsächlich den Text erhalten hat, der übereinstimmen sollte. Könnten Sie mir bitte dabei helfen? Danke vielmals. – kurkum

+0

Ich bin mir nicht sicher, ob ich das Problem verstehe. Bitte aktualisieren Sie die Frage mit dem, was Sie versucht haben, der Ausgabe und der gewünschten Ausgabe (schließen Sie auch ein Beispiel mit '$ matches [0]' etc. ein.). Es ist schwierig für mich zu debuggen, ohne zu wissen, wie die Eingabe aussieht. Myabe du könntest eine der tempfiles auf pastebin oder etwas teilen (extrahiert von einem Test-zip ohne irgendwelche senstivie Daten)? 'if ($ content -match ' (. *)') {$ Matches [0]}' sollte ' irgendeinen Wert' zurückgeben, während '$ Matches [1]' nur einen Wert "output" hätte. Wenn '$ matches [0]' only Gibt '/' zurück, stimmt etwas nicht. –

Verwandte Themen