提问人:HTWingNut 提问时间:11/14/2023 更新时间:11/14/2023 访问量:98
使用 PowerShell,如何从一行文本中提取文件路径和名称?
Using PowerShell, how do I extract just the file path and name from a line of text?
问:
如果我正在遍历一个文本文档,每一行都有一个这样的输出:
Newer 432416 2020/04/04 01:50:14 S:\Steam\SteamLibrary\steam.dll
我只想提取文件名和路径:S:\Steam\SteamLibrary\steam.dll
我知道我是否将该行存储在变量中$textline = " Newer 432416 2020/04/04 01:50:14 S:\Steam\SteamLibrary\steam.dll"
我可以简单地使用以下结果:$textline.split (":")[-1]
\Steam\SteamLibrary\steam.dll
但是我如何让它包含驱动器号?有没有办法告诉它之前抓取一个字符并包含分隔符?S:
谢谢。
答:
3赞
mandy8055
11/14/2023
#1
您可以使用下面的正则表达式匹配来搜索每行中的文件路径
([A-Z]:\\(?:[^\\]+\\)*[^\\]+)$
上述正则表达式的解释:
[A-Z]:
- 匹配驱动器名称,后跟文本 。在我用于不区分大小写的匹配的脚本中。:
?i
- \\
(?:[^\\]+\\)*
- (因为它是一个特殊字符,所以需要转义),后跟一个与至少一个字符匹配的非捕获组 except()。非捕获组可以存在 0 次或更多次,因为可以有嵌套路径。在这里,您还可以包含换行符否定列表。请看这里。我没有这样做,因为我们正在迭代一行,所以它不是必需的。\
\
[^\\]+
- 最后,这部分匹配任何不是反斜杠的字符,基本上与路径的文件名匹配。$
- 表示行尾。
$text_file = "path_to_your_file.ext"
$lines = Get-Content $text_file
$pattern = "(?i)([A-Z]:\\(?:[^\\]+\\)*[^\\]+)$"
foreach ($textline in $lines) {
$match = [regex]::Match($textline, $pattern)
if ($match.Success) {
$file_path = $match.Groups[1].Value
Write-Host $file_path
}
}
评论
0赞
HTWingNut
11/14/2023
是的,谢谢,我会试一试!我对正则表达式不太熟悉,我想我必须再读一遍。我也在想,如果它是以双斜杠“\”开头的 UNC 路径。使用您提供的演示站点,我设法使 UNC 路径正常工作,但不确定它是否最佳甚至正确:regex101.com/r/4Yyl1G/1
1赞
mandy8055
11/14/2023
@HTWingNut我会帮助你的。所以你是说如果路径以双斜杠开头并且没有驱动路径怎么办,对吧?
0赞
HTWingNut
11/14/2023
是的!好吧,它可能是带有冒号或双斜杠的驱动器号开始。
1赞
mandy8055
11/14/2023
@HTWingNut,好吧,那么你可以使用交替。类似 regex101.com/r/uXkZzc/1
1赞
HTWingNut
11/14/2023
这看起来可能会起作用!非常感谢!
3赞
Thomas
11/14/2023
#2
mandy8055 的回答会仔细检查路径是否有效,但如果你知道文件路径总是在 的末尾,并且 中的“列”用 4 个空格(或更多)分隔,那么这个正则表达式要快得多:$textLine
$textLine
(?:.*\s{4})(.*)$
这个正则表达式的逻辑是简单地找到“最后 4 个空格”之后的所有字符,没有检查它是否是路径。
使用示例:
if($textLine -match "(?:.*\s{4})(.*)$"){
$path = $matches[1]
# process the path etc.
}
评论
[regex]::split($textline, "\s{2}")[-1]
$textline | ConvertFrom-SourceTable -Header Newer,Size,Date,Time,Filepath
$textdocument | ConvertFrom-SourceTable | Foreach { $_.<filepath header> }