我有一个现有的工作代码来解压缩gz格式的文件:
\author{...}
是否可以使用此代码解压缩文件夹中的所有.gz文件?参数如何传递给脚本。我假设现在不是文件名,而是应该查找输入目录和目标文件夹。
答案 0 :(得分:1)
目前看来它只是看起来像是在问你如何将你的功能融入循环中。 Etan Reisner试图帮助你做到这一点。在他的评论的基础上,你可以做一些事情。此信息位于about_functions
$path = "c:\temp\somepath"
Get-ChildItem -Path $path -Filter "*.gz" | ForEach-Object{
DeGZip-File -inifile $_.FullName
# Or the following would also work
# DeGZip-File $_.FullName
}
根据您的功能设置方式, -outfile
可视为可选项。如果你需要通过函数调用声明它,那么你只需要在循环中执行此操作
DeGZip-File -inifile $_.FullName -outfile "otherFileName"
或
DeGZip-File $_.FullName "SomehtingElse"
<强>除了强>
考虑查看Advanced Functions,您可以让您的函数接受管道输入。
答案 1 :(得分:1)
正如其他人所提到的,您可以简单地将您的函数合并到ForEach-Object循环中。或者,如果您创建两个参数集,并且在一个参数集中保留它,并且另一个参数集接受参数上的管道值,并使该参数成为[FileInfo]
对象,则可以轻松使用Get-ChildObject
管道到你的功能,甚至不必使用循环。至于想要在另一个文件夹中输出,请在函数中添加一个参数,并使用一点内部逻辑来适应...
Function DeGZip-File{
[cmdletbinding(DefaultParameterSetName='Piped')]
Param(
[Parameter(ParameterSetName='Direct')][String]$infile,
[Parameter(ParameterSetName='Direct')][String]$outfile = ($infile -replace '\.gz$',''),
[Parameter(ParameterSetName='Piped',ValueFromPipeline=$true)][System.IO.FileInfo[]]$PipedFile,
[Parameter(ParameterSetName='Piped')]$Redirect=$null,
[Switch]$PassThru
)
Process{
If($PsCmdlet.ParameterSetName -eq 'Piped'){
$infile = $PipedFile.FullName
$outfile = If([string]::IsNullOrEmpty($Redirect)){$infile -replace '\.gz$',''}else{Join-Path $Redirect -ChildPath ($PipedFile.BaseName)}
}
$inputfile = New-Object System.IO.FileStream $inFile, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read)
$output = New-Object System.IO.FileStream $outFile, ([IO.FileMode]::Create), ([IO.FileAccess]::Write), ([IO.FileShare]::None)
$gzipStream = New-Object System.IO.Compression.GzipStream $inputfile, ([IO.Compression.CompressionMode]::Decompress)
$buffer = New-Object byte[](1024)
$read = $gzipstream.Read($buffer, 0, 1024)
Do{
$output.Write($buffer, 0, $read)
$read = $gzipstream.Read($buffer, 0, 1024)
}While($read -gt 0)
$gzipStream.Close()
$output.Close()
$inputfile.Close()
If($PassThru){[System.IO.FileInfo]$outfile}
}
}
我还添加了一个-PassThru
开关,以防您想要查看它提取的文件。
编辑:我忘了包含一个用法示例,我的不好......
Get-ChildItem "C:\Temp\GZippedFiled\*.gz" | DeGZip-File -Redirect "C:\Temp\Unzipped" -PassThru
这将解压缩&#34; C:\ Temp \ GZippedFiled&#34;中的所有.GZ文件。文件夹,并将在&#34; C:\ Temp \ Unzipped&#34;中写入具有相同(减去.gz)文件名的解压缩文件。夹。它还会显示它提取的文件,显示每个文件的[fileinfo]对象(Mode,LastWriteTime,Length和Name)。或者你可以更简单地做到这一点,只需管道到没有任何参数的函数,它会在适当的位置提取它们而不向控制台输出任何内容。
它也接受旧的用法,ala:
DeGZip-File -infile "C:\Path\To\File.gz" -outfile "C:\Path\To\NewFile.ext"
Edit2:好的,只是为了确保我在评论中理解了这个问题。我们假设您压缩了2个文件:
C:\Temp\Resume.docx.gz
C:\Temp\Cover Letter.docx.gz
您想要解压缩它们,并将结果文件存储在C:\Temp\Unzipped
中(目标文件夹应该已经存在)。您的脚本应该具有顶部的功能,然后您可以根据需要定义路径,然后将Get-ChildItem
传递给函数。看起来应该是这样的:
Function DeGZip-File{
<function code goes here>
}
$FullPath = 'C:\Temp\'
$DestinationPath = 'C:\Temp\Unzipped'
Get-ChildItem -Path $fullpath -Filter "*.gz" | DeGZip-File -Redirect $destinationpath -PassThru
我只是将这个答案中的函数复制到一个新的PowerShell ISE实例,将2 .gz文件放在我的C:\ Temp文件夹中,创建了一个C:\ Temp \ Unzipped文件夹,然后运行上面的代码。它功能完美。提取的文件,它向我展示了它们的详细信息。路径上的尾随反斜杠并不重要,两者都没有,或者两条路径都没有或者没有反斜杠,并且因为join-path
消毒而无法产生差异它