在PowerShell中将字符串转换为目录对象

19

我使用 Get-Content 和 foreach 循环从文件逐行读取字符串,我想将这些字符串转换为目录对象(以便我可以访问像 .FullName 这样的属性)。如何轻松地将字符串转换为目录?

对于文件,这很容易:$myFileAsFile = $myFileAsStr | dir $_,但是,如何获得 $directoryAsString 的目标呢?


你是指 $myFileAsFile = $myFileAsStr | dir { $_ } 吗?否则我不明白它怎么可能起作用。 - js2010
6个回答

25

好的,答案似乎是Get-Item

$dirAsStr = '.\Documents'
$dirAsDir = Get-Item $dirAsStr
echo $dirAsDir.FullName

有效!


2
只有当该项实际上存在时,此操作才会生效。根据您的问题,文件中的字符串是否涉及实际目录并不清楚。 - arco444
在我的情况下,它们总是存在的 - 你有一个在一般情况下也能工作的更好的解决方案吗? - D.R.
为了处理可能不存在的文件夹:如果(Test-Path $dirAsStr){$dirAsDir = Get-Item $dirAsStr}else{$dirAsDir = md $dirAsStr} - EBGreen

23

您可以使用 .Net 类 System.IO.FileInfoSystem.IO.DirectoryInfo。即使目录不存在,这也可以工作:

$c = [System.IO.DirectoryInfo]"C:\notexistentdir"
$c.FullName

它甚至可以使用文件:

$c = [System.IO.DirectoryInfo]"C:\some\file.txt"
$c.Extension

所以要检查它是否真的是一个目录,请使用:

$c.Attributes.HasFlag([System.IO.FileAttributes]::Directory)

下面的评论中有一个使用了 System.IO.FileInfo 的示例。


2
为了其他人参考,如果你需要从文件名的字符串中获取目录,可以使用 [System.IO.FileInfo]$filename = "文件路径" 来获取文件对象。然后你可以使用 $filename.directory 来获取它的目录。虽然有点离题,但以防你和我一样来到这里。 - Ty Savercool
<redacted for dumb mistake> - Teknowledgist
1
该方法不处理相对路径,而Get-Item则可以。不确定它是否会影响其他人,但对于我的用例确实如此。([System.IO.FileInfo]'.\myfile.txt').FullName无论当前文件夹是什么,都会生成C:\Windows\System32\myfile.txt - Code39
DirectoryInfo类有SetCurrentDirectory方法。我认为它不使用或不应该使用PowerShell环境。 - Mikhail Tumashenko

5

因此,我通常使用以下简单方法从字符串类型变量获取路径/完整路径:

(Resolve-Path $some_string_var)

Set-Variable -Name "str_path_" -Value "G:\SO_en-EN\Q33281463\Q33281463.ps1"

$fullpath = (Resolve-Path $some_string_var) ; $fullpath


为什么在 (Resolve-Path ...) 前面要加上 $ 符号? - user310291
@user310291 只是分心了,谢谢评论 d:) - Io-oI

1

Get-item将根据输入输出FileInfo或DirectoryInfo对象。或者可以使用管道符号传递给get-item -path { $_ }

$myFileAsFile = get-item $myFileAsStr
$directoryAsDir = get-item $directoryAsString

0

快速的方法

# "Get-Item" automatically grabs $Path item as an object if it exists.
# Carry on your merry way.
$FSO = Get-Item -Path $Path -Force

以上代码可以正常工作,但容易受到不良输入的影响。因此,结合之前的一些评论和一些输入验证...
# Get path string (via parm, pipeline, etc.)
# Can be full path ('c:\users\Me') or properly formatted relative path ('..\..\Logs').
$Path = '<some_string>'

# Never presume the input actually exists, so check it with "Test-Path".
# Note: If the string is a file and ends with "\", this check will fail (generate an error).
# YMMV: add add'l code to strip off trailing "\" unless it's a drive (e.g., "C:\") prior to the check.
if (Test-Path $Path -PathType Leaf) {
    $PathType = 'File'
} elseif (Test-Path $Path -PathType Container) {
    $PathType = 'Folder'
} else {$PathType = $null}

# "Get-Item" automatically grabs item as an object if it exists.
if ($PathType) {
    $FSO = Get-Item -Path $Path -Force
    Write-Host 'Object is:' $PathType
    Write-Host 'FullName: ' $FSO.FullName
} else {
    Write-Host 'Bad path provided.'
    exit
}

# Some Test-Path samples:
$Path = 'c:\windows\'             # Folder: Test-Path works
$Path = 'c:\windows'              # Folder: Test-Path works
$Path = 'c:\windows\system.ini'   # File: Test-Path works
$Path = 'c:\windows\system.ini\'  # File: Test-Path FAILS
$Path = '..\system.ini'           # File: Test-Path works
$Path = '..\system.ini\'          # File: Test-Path FAILS

以上代码有些不够简洁,需要优化...

  • 处理尾部 "\" 的问题
  • 使用 ".GetType()" 来获取 FSO 的对象类型,以实现特定的处理。
# Get path string (via parm, pipeline, etc.)
$Path = '<some_string>'

# Remove trailing "\" on all but drive paths (e.g., C:\, D:\)
if ($Path.EndsWith("\")) {
    if ($Path.Length -gt 3) {
        $Path = $Path.Remove($Path.Length - 1)
    }
}

# If the provided path exists, do stuff based on object type
# Else, go another direction as necessary
if (Test-Path -Path $Path) {
    $FSO = Get-Item -Path $Path -Force
    if ($FSO.GetType().FullName -eq "System.IO.DirectoryInfo") {
        Write-Host "Do directory stuff."
    } elseif ($FSO.GetType().FullName -eq "System.IO.FileInfo") {
        Write-Host "Do file stuff."
    } else {
         Write-Host "Valid path, but NOT a file system object!! (could be a registry item, etc.)"
    }
    Write-Host $FSO.FullName
} else {
    Write-Host "Path does not exist. Bail or do other processing, such as creating the path."
    $FSO = $null
}

-2

$(Get-Item $directoryAsString).FullName

$(获取项 $directoryAsString).全名


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接