如何删除文本文件中列出的目录路径,但保留文件路径?



我有一个包含数千行的文本文件,其中包含目录路径和文件路径。我想循环遍历文本文件的每一行,并删除包含目录路径的任何行,并保留包含文件路径的所有行。两行示例(一个目录和文本文件的一个路径):

exampleDirectoryPath/tags/10.0.0.8/tools/
exampleFilePath/tags/10.0.0.8/tools/hello.txt
到目前为止,循环遍历文本文件,我有:
foreach ($line in [System.IO.File]::ReadLines("file.txt")) {
if ($line -match ".*/.*$") {
$line
}
}

目标输出:

exampleFilePath/tags/10.0.0.8/tools/hello.txt

注意:我不想硬编码文件扩展名。有成千上万的文件要遍历,我不知道有哪些扩展名,所以我想返回所有的文件。

所以,这里的基本逻辑很简单:

Get-Content "file.txt" | where { $_ is a file path... }

这取决于你想如何确定,如果它是一个文件路径

如果您的所有目录路径都以"/"结尾,您可以简单地执行:

where { -not $_.EndsWith("/") }

或:

where { [system.io.Path]::GetFileName($_) -eq "" }

如果没有,但是你所有的文件路径都有扩展名,你可以这样做:

where { [system.io.Path]::GetExtension($_) -ne "" }

如果所有的路径都存在,你也可以这样做:

where { Test-Path $_ -Type Leaf }

提供简洁且性能良好的解决方案:

(Get-Content -ReadCount 0 file.txt) -notmatch '\$'
  • 使用-ReadCount 0Get-Content是一种性能优化,它将输入文件中的所有行返回为单个数组对象,而不是逐个收集行。

    • 另外,-ReadCount 0确保输出数组,即使输入文件碰巧只有一行
  • -notmatch是基于正则表达式的-match运算符的否定形式,作为过滤器数组值的LHS,返回(非)匹配的元素(行)(作为新数组)。

    • Regex\$匹配每个输入字符串(行)的末尾($)的逐字

注意:正如你的问题所暗示的,上面的解决方案假设目录可以根据输入文件中的行是否以/结尾来区分文件

我个人不会为此使用regex,原因很简单,即使您可能能够验证路径的模式是否与文件或文件夹的模式匹配,但它无法验证它是否实际存在。我将在你的代码下面使用它:

$result = foreach($line in [System.IO.File]::ReadLines("file.txt"))
{
if(([System.IO.DirectoryInfo]$line).Attributes -eq 'Archive')
{
$line
}
}

最新更新