如何删除文本文件中列出的目录路径但保留文件路径?
How can I remove directory paths listed in a text file but keep the file paths?
我有一个包含数千行的文本文件,其中包含目录路径和文件路径。
我想遍历文本文件的每一行并删除包含目录路径的所有行,并保留所有包含文件路径的行。两行示例(一个目录,一个来自文本文件的路径):
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
注意:我不想硬编码文件扩展名。有成千上万的文件要遍历,我不知道有哪些扩展名,所以我想 return 所有文件。
所以,这里的基本逻辑很简单:
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 }
我个人不会为此使用 regex
,原因很简单,即使您可以验证路径的模式是否与文件或文件夹的模式匹配,它也无法验证它是否真的存在。我会按照你的代码使用它:
$result = foreach($line in [System.IO.File]::ReadLines("file.txt"))
{
if(([System.IO.DirectoryInfo]$line).Attributes -eq 'Archive')
{
$line
}
}
提供简洁且性能良好的解决方案:
(Get-Content -ReadCount 0 file.txt) -notmatch '\$'
使用 -ReadCount 0
和 Get-Content
是一种性能优化,returns 输入文件中的所有行作为 单个数组对象 而不是一行一行地收集行。
- 此外,
-ReadCount 0
确保输出 array 即使输入文件恰好只有 one 行。
-notmatch
,regex-based -match
operator 的否定形式,作为 filter 和 array-valued LHS,返回(非)匹配元素(行)(作为新数组)。
- 正则表达式
\$
匹配每个输入字符串(行)末尾 ($
) 的逐字 \
。
注意:正如你的问题所暗示的,上面的解决方案假设目录可以正式与文件区分开,基于输入文件中的行是否以[=19=结尾] ] 与否。
我有一个包含数千行的文本文件,其中包含目录路径和文件路径。 我想遍历文本文件的每一行并删除包含目录路径的所有行,并保留所有包含文件路径的行。两行示例(一个目录,一个来自文本文件的路径):
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
注意:我不想硬编码文件扩展名。有成千上万的文件要遍历,我不知道有哪些扩展名,所以我想 return 所有文件。
所以,这里的基本逻辑很简单:
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 }
我个人不会为此使用 regex
,原因很简单,即使您可以验证路径的模式是否与文件或文件夹的模式匹配,它也无法验证它是否真的存在。我会按照你的代码使用它:
$result = foreach($line in [System.IO.File]::ReadLines("file.txt"))
{
if(([System.IO.DirectoryInfo]$line).Attributes -eq 'Archive')
{
$line
}
}
提供简洁且性能良好的解决方案:
(Get-Content -ReadCount 0 file.txt) -notmatch '\$'
使用
-ReadCount 0
和Get-Content
是一种性能优化,returns 输入文件中的所有行作为 单个数组对象 而不是一行一行地收集行。- 此外,
-ReadCount 0
确保输出 array 即使输入文件恰好只有 one 行。
- 此外,
-notmatch
,regex-based-match
operator 的否定形式,作为 filter 和 array-valued LHS,返回(非)匹配元素(行)(作为新数组)。- 正则表达式
\$
匹配每个输入字符串(行)末尾 ($
) 的逐字\
。
- 正则表达式
注意:正如你的问题所暗示的,上面的解决方案假设目录可以正式与文件区分开,基于输入文件中的行是否以[=19=结尾] ] 与否。