以下是我目前使用的代码:
# 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文件。
答案 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
作为旁注,我使用wildcards和call 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
}