请参阅以下代码:
# 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 *
这种输出格式对我来说最有用。
答案 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)}}