【发布时间】:2019-10-12 14:22:16
【问题描述】:
由于几个不相关的原因,我在使用Get-ChildItem 命令时尝试了几种过滤管道输出的方法。
我创建了一个简短的代码来举例说明我的意思。当我使用不同的方式来获取同一个项目时,即使每次都是同一个项目,项目的“字符串化”也会根据它被发现的方式而不同。
假设我们有这个文件夹C:\Folder1\Folder1-a,里面有File1.7z 和File2.txt。
Folder1 里面还有更多的File1-X 文件夹,每个文件夹里面都有一个.7z 和一个.txt 文件,它们的名字可以有一些特殊字符,比如方括号。这与这个问题无关,但这就是为什么我更愿意使用某种特定的过滤方式而不是另一种过滤方式的原因(在附加代码的 cmets 中进行了解释)。
下面的代码可以说明我的观点:
#Initialize 7zip
if (-not (test-path "$env:ProgramFiles\7-Zip\7z.exe")) {throw "$env:ProgramFiles\7-Zip\7z.exe needed"}
set-alias 7zip "$env:ProgramFiles\7-Zip\7z.exe"
#this is a placeholder, $TXTFile would be the result of an iteration over a previous Item array
$TXTFile = Get-Item -Path "C:\Folder1\Folder1-a\File2.txt"
#Now there comes 3 different ways to select the 7z file in the same directory as File2.txt
# I use this to modify the path name so square brackets are properly escaped
$directory1 =$TXTFile.DirectoryName -replace "\[","`````[" -replace "\]","`````]"
[array]$7ZFile1 = Get-ChildItem -File -Path "$directory1\*.7z"
# This option uses LiteralPath so no modification is needed.
# More convenient since it supports any kind of special character in the name.
$directory2=$TXTFile.DirectoryName
[array]$7ZFile2= Get-ChildItem -File -LiteralPath $directory2 -Filter *.7z
# This option uses LiteralPath so no modification is needed.
# More convenient since it supports any kind of special character in the name.
$directory3=$TXTFile.DirectoryName
[array]$7ZFile3 = Get-ChildItem -File -LiteralPath $directory3 | Where-Object {$_.Extension -eq ".7z"}
#Lets see each item. They all seem equal
$7ZFile1
$7ZFile2
$7ZFile3
Write-Host "`n"
#Lets see how they have he same FullName
Write-Host $7ZFile1.FullName
Write-Host $7ZFile2.FullName
Write-Host $7ZFile3.FullName
Write-Host "`n"
#Lets compare them using -eq. Damn, they are not equal
if($7ZFile1 -eq $7ZFile2){"7ZFile1=7ZFile2"}Else{"7ZFile1!=7ZFile2"}
if($7ZFile2 -eq $7ZFile3){"7ZFile2=7ZFile3"}Else{"7ZFile2!=7ZFile3"}
if($7ZFile3 -eq $7ZFile1){"7ZFile3=7ZFile1"}Else{"7ZFile3!=7ZFile1"}
Write-Host "`n"
#This is relevant if we "stringify" each object. First one returns FullName, the two others return Name
Write-Host $7ZFile1
Write-Host $7ZFile2
Write-Host $7ZFile3
Write-Host "`n"
#Example of this being relevant. Inside File1.7z is a txt file. If you use 7zip por example like this:
7zip t $7ZFile1 *.txt -scrc #Success
7zip t $7ZFile2 *.txt -scrc #Fail, can't find 7ZFile2
7zip t $7ZFile3 *.txt -scrc #Fail, can't find 7ZFile3
我使用$7ZFile.FullName 始终如一地获得我想要的字符串,但是我想知道为什么会发生这种情况?首先为什么会有差异?
【问题讨论】:
-
为什么会发生what?我们看不到您的屏幕
-
你说得对,我添加了一些说明,但是我已经编写了如何设置所有内容并附上了一个注释脚本,详细解释了整个事情。您不需要查看我的屏幕,您只需要执行相同的脚本并查看您自己的屏幕。在任何情况下,问题是过滤 Get-ChildItem 管道的不同方式会导致完全相同的项目,由于某种原因表现不同。它们看起来一样,指向同一个文件,但是当“字符串化”时,它们会返回不同的东西。
-
与问题没有直接关系,但您可能想使用
where.exe来检查7z,例如:if (!(where.exe 7z 2>$null)) {<# 7-zip does not exist #>;exit} -
使用@AP 有什么好处?
-
这允许您验证
7z是否在路径中的某个位置并且可以执行,但不限于您硬编码的路径。 (支持:自定义安装、非标准windows驱动等)
标签: powershell filtering get-childitem