我有一个包含数千行的文本文件,其中包含目录路径和文件路径。我想循环遍历文本文件的每一行,并删除包含目录路径的任何行,并保留包含文件路径的所有行。两行示例(一个目录和文本文件的一个路径):
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 0
和Get-Content
是一种性能优化,它将输入文件中的所有行返回为单个数组对象,而不是逐个收集行。- 另外,
-ReadCount 0
确保输出数组,即使输入文件碰巧只有一行。
- 另外,
-notmatch
是基于正则表达式的-match
运算符的否定形式,作为过滤器与数组值的LHS,返回(非)匹配的元素(行)(作为新数组)。- Regex
\$
匹配每个输入字符串(行)的末尾($
)的逐字。
- Regex
注意:正如你的问题所暗示的,上面的解决方案假设目录可以根据输入文件中的行是否以/
结尾来区分文件。
我个人不会为此使用regex
,原因很简单,即使您可能能够验证路径的模式是否与文件或文件夹的模式匹配,但它无法验证它是否实际存在。我将在你的代码下面使用它:
$result = foreach($line in [System.IO.File]::ReadLines("file.txt"))
{
if(([System.IO.DirectoryInfo]$line).Attributes -eq 'Archive')
{
$line
}
}