我如何更新此代码以便第二次运行但仅在已解压缩的zip存档上运行?

时间:2016-11-13 03:06:03

标签: powershell zip zipfile 7zip

以下是我目前使用的代码:

# Don't include "\" at the end of $NewSource - it will stop the script from
# matching first-level subfolders
$ignore = "somename"
$files = gci $NewSource -recurse | Where {
    $_.Extension -match "zip||prd" -and $_.FullName -notlike $ignore
}
foreach ($file in $files) {
    $NewSource = $file.FullName
    # Join-Path is a standard Powershell cmdLet
    $destination = Join-Path (Split-Path -Parent $file.FullName) $file.BaseName
    Write-Host -Fore green $destination
    $destination = "-o" + $destination
    # Start-Process needs the path to the exe and then the arguments passed
    # separately. You can also add -wait to have the process complete before
    # moving to the next
    Start-Process -FilePath "C:\Program Files\7-Zip\7z.exe" -ArgumentList "x -y $NewSource $destination" -Wait
}

但是,一旦完成,我需要返回新目录并解压缩仅在解压缩.zip存档后创建的.prd文件。需要一些帮助,因为我的尝试不起作用,并且当前解压缩并覆盖所有以前解压缩的.prd和.zip文件。

1 个答案:

答案 0 :(得分:1)

already told you $_.Extension -match "zip||prd"匹配所有扩展名,因为正则表达式中两个|字符之间的空字符串(所有字符串都包含空字符串)。

此外,-notlike-like运算符与-ne-eq运算符的行为完全类似于将值与不具有{{的模式进行比较3}},因此您的第二个条件将匹配所有文件的全名不是完全"某些名称"。

改变这个:

$ignore = "somename"
$files = gci $NewSource -recurse | Where {
    $_.Extension -match "zip||prd" -and $_.FullName -notlike $ignore
}

进入这个:

$ignore = "*somename*"
$files = gci $NewSource -recurse | Where {
    $_.Extension -match "zip|prd" -and $_.FullName -notlike $ignore
}

并且代码应该按照您的期望进行。

作为替代方案,您可以构建一个您要忽略的路径列表

$ignore = 'C:\path\to\first.zip',
          'C:\other\path\to\second.zip',
          'C:\some\file.prd',
          ...

并使用-notin(PowerShell v3或更高版本)或-notcontains运算符排除这些文件:

$_.FullName -notin $ignore
$ignore -notcontains $_.FullName

作为旁注,我使用wildcardscall operator代替Start-Process来调用7zip.exe

$destination = Join-Path (Split-Path -Parent $file.FullName) $file.BaseName
$params      = 'x', '-y', $NewSource, "-o$destination"
& "${env:ProgramFiles}\7-Zip\7z.exe" @params

要提取从zip存档中提取的.prd文件,请在循环中添加另一个步骤。

foreach ($file in $files) {
    ...
    & "${env:ProgramFiles}\7-Zip\7z.exe" @params
    Get-ChildItem $destination | Where-Object {
        $_.Extension -eq 'prd'
    } | ForEach-Object {
        # extract matching file here, procedure is the
        # same as with the files in the outer loop
    }
}

您可能希望包装用于构建目标路径的代码并在读取路径splatting的函数中提取文件,并在目标路径包含.prd文件时递归调用自身。

function Invoke-Unzip {
    [CmdletBinding()]
    Param(
        [Parameter(
            Mandatory=$true,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true
        )]
        [ValidateScript({Test-Path -LiteralPath $_})]
        [string]$FullName
    )

    $newSource = $FullName
    ...
    & "${env:ProgramFiles}\7-Zip\7z.exe" @params
    Get-ChildItem $destination |
        Where-Object { $_.Extension -eq 'prd' } |
        Invoke-Unzip
}