PowerShell - 提取文件的元数据和网格查看它

时间:2016-05-17 19:56:01

标签: powershell metadata extract

请参阅以下代码:

# 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();
}
}

它是我在互联网上找到的修改后的代码版本,帮助我在zip文件中找到字符串。

我现在的意图是使用此代码从zip文件中提取元数据。

我不明白如何在不同的行中显示这两种类型的信息。如果只运行一个Select-String...管道线运行脚本,则代码按预期工作。如果激活(取消注释)第二个Select-String...管道线,则不会显示第二类信息(<dc:title>值),而是显示空行。

请帮帮我:

1)如何使用我在代码中使用的dc:title机制显示Select-String | Select-Object值。

2)如何以表格格式输出所有数据,因此表格如下所示:

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

这种输出格式对我来说最有用。

2 个答案:

答案 0 :(得分:1)

控制台&#34;查看&#34; for pipeline-objcts是基于第一个对象(只有Path - 属性)创建的。第二个对象缺少Path - 属性,这就是为什么你看到一个空行。如果您已注释掉第一个Select-String .. - 行(显示Path),那么第二行就可以了。

通过管道发送的对象应具有相同的属性集,因此请避免使用具有不同属性集的select-object。例如:

.....

$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;
}

.....

要输出所有元数据,您应该创建一个包含所有值的对象。例如:

$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;
}

....

实施例。输出

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

如果你真的想要强制单独的视图(会变丑),那么你需要每次都将对象发送到| Out-Default来创建一个新视图,例如:

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

答案 1 :(得分:0)

我知道这不是您正在寻找的答案,但作为临时解决方法,您可以将这两个命令合并为一个这样的

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