You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PowerShell获取目录文件并在另一目录搜索后导出CSV?

问题:使用PowerShell批量搜索文件并导出CSV结果

我需要用PowerShell实现以下需求:

  1. 获取指定目录(比如C:\Temp)下的所有文件名及完整路径
  2. 逐个在另一目标目录(比如C:\Filesnew)中搜索这些文件
  3. 导出包含以下字段的CSV文件:
    • Filename:原文件名
    • Filepath:原文件的完整路径
    • Found?:是否找到(y/n)
    • FoundIn:找到时的完整路径,未找到则为空

示例场景

原目录C:\Temp下的文件:

  • C:\Temp\Test2\Test.docx
  • C:\Temp\Test\test.txt
  • C:\Temp\Test\file.html

期望导出的CSV格式:

FilenameFilepathFound?FoundIn
Test.docxC:\Temp\Test2\Test.docxyC:\Filesnew\TransferedFiles\Test.docx
test.txtC:\Temp\Test\test.txtn
file.htmlC:\Temp\Test\file.htmlyC:\Filesnew\webfiles\file.html

我当前的代码卡在这儿,求帮忙修正:

$files = gci -r *   | select-object name, fullname
foreach ($file in $files)
{
  gci -path C:\Filesnew -recurse | where {$_.Name -match $file.Name} | select-object $files.Name $files.fullname, $file.fullname | Export-CSV C:\test.csv  
}     

解决方案

原代码的问题分析

  1. 效率极低:循环内每次都递归遍历目标目录,文件数量多的时候会重复做大量无用功
  2. 语法错误:select-object的参数写法错误,变量引用混乱,没有构建需要的字段
  3. 结果覆盖:每次循环都调用Export-CSV,默认会覆盖之前的结果,最终只保留最后一个文件的搜索记录
  4. 匹配风险:使用-match会把文件名当作正则表达式处理,比如test.txt会意外匹配test1.txt这类文件

修正后的代码

# 定义原目录、目标目录和输出CSV路径
$sourceDir = "C:\Temp"
$targetDir = "C:\Filesnew"
$outputCsv = "C:\test.csv"

# 获取原目录下所有文件的完整列表(只取文件,排除目录)
$sourceFiles = Get-ChildItem -Path $sourceDir -Recurse -File

# 预先遍历目标目录,构建文件名到路径的映射表,提升搜索效率
$targetFileMap = @{}
Get-ChildItem -Path $targetDir -Recurse -File | ForEach-Object {
    # 若目标目录有重名文件,这里会保留最后一个,可根据需求调整逻辑
    $targetFileMap[$_.Name] = $_.FullName
}

# 批量生成结果对象
$results = foreach ($file in $sourceFiles) {
    $foundPath = $targetFileMap[$file.Name]
    [PSCustomObject]@{
        Filename = $file.Name
        Filepath = $file.FullName
        'Found?' = if ($foundPath) { 'y' } else { 'n' }
        FoundIn  = $foundPath ?? ''
    }
}

# 一次性导出所有结果到CSV
$results | Export-Csv -Path $outputCsv -NoTypeInformation -Encoding UTF8

代码说明

  • 预构建映射表:只遍历一次目标目录,把文件名和对应路径存入哈希表,后续直接通过键值查找,效率提升明显
  • 精准匹配:用文件名直接作为哈希表的键,避免正则匹配的意外问题
  • 正确构建字段:通过PSCustomObject严格定义CSV需要的四个字段,确保输出格式符合预期
  • 避免结果覆盖:先收集所有结果,再一次性导出到CSV,保证所有记录都被保存

处理目标目录重名文件的版本

如果目标目录存在多个同名文件,可修改代码将所有匹配路径用分号分隔:

# 定义路径
$sourceDir = "C:\Temp"
$targetDir = "C:\Filesnew"
$outputCsv = "C:\test.csv"

$sourceFiles = Get-ChildItem -Path $sourceDir -Recurse -File

# 构建文件名到路径数组的映射
$targetFileMap = @{}
Get-ChildItem -Path $targetDir -Recurse -File | ForEach-Object {
    if (-not $targetFileMap.ContainsKey($_.Name)) {
        $targetFileMap[$_.Name] = @()
    }
    $targetFileMap[$_.Name] += $_.FullName
}

$results = foreach ($file in $sourceFiles) {
    $foundPaths = $targetFileMap[$file.Name]
    [PSCustomObject]@{
        Filename = $file.Name
        Filepath = $file.FullName
        'Found?' = if ($foundPaths) { 'y' } else { 'n' }
        FoundIn  = if ($foundPaths) { $foundPaths -join ';' } else { '' }
    }
}

$results | Export-Csv -Path $outputCsv -NoTypeInformation -Encoding UTF8

内容的提问来源于stack exchange,提问作者rdkli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 01:05:19