【问题标题】:Select directory from a file从文件中选择目录
【发布时间】:2016-03-17 01:24:05
【问题描述】:

我需要我的程序为我提供包含超出 Windows 字符数限制的文件的每个文件夹。这意味着如果一个文件有超过 260 个字符(文件夹为 248 个),我需要它来写入文件父级的地址。我需要它只写一次。目前,我正在使用以下代码:

$maxLength = 248

Get-ChildItem $newPath -Recurse |
    Where-Object { ($_.FullName.Length -gt $maxLength) } |
    Select-Object -ExpandProperty FullName |
    Split-Path $_.FullName

但是Split-Path 不起作用(这是我第一次使用它)。它告诉我-Path 参数有一个空值(我可以写-Path 但它不会改变任何东西)。

如果您想要一个我需要的示例:假设 folder3 有一个 230 个字符的地址,file.txt 有一个 280 个字符的地址:

C:\users\folder1\folder2\folder3\file.txt

会写:

C:\users\folder1\folder2\folder3

顺便说一句,我正在使用 PS2。

【问题讨论】:

    标签: windows powershell


    【解决方案1】:

    剧透:您正在构建的工具可能无法报告超出限制的路径,因为Get-ChildItem 无法访问它们。不过您可以尝试,也可以在底部的链接中找到其他解决方案。

    代码中的问题: $_ 仅适用于特定上下文,例如 ForEach-Object 循环。

    但是在这里,在管道的末尾,您只剩下一个包含完整路径的字符串(不再是完整的文件对象),因此直接将其传递给 Split-Path 应该可以:

    $maxLength = 248
    
    Get-ChildItem $newPath -Recurse |
        Where-Object { ($_.FullName.Length -gt $maxLength) } |
        Select-Object -ExpandProperty FullName |
        Split-Path
    

    因为"C:\Windows\System32\regedt32.exe" | Split-Path 将输出C:\Windows\System32

    旁注:(Get-Item C:\Windows\System32\regedt32.exe).DirectoryName(Get-Item C:\Windows\System32\regedt32.exe).Directory.FullName 在您的计算机上输出什么?这些都显示了我系统上的目录。

    改编代码示例:

    $maxLength = 248
    
    Get-ChildItem $newPath -Recurse |
        Where-Object { ($_.FullName.Length -gt $maxLength) } |
        ForEach-Object { $_.Directory.FullName } |
        Select-Object -Unique
    

    关于MAX_PATH的其他信息:

    How do I find files with a path length greater than 260 characters in Windows?

    Why does the 260 character path length limit exist in Windows?

    http://www.powershellmagazine.com/2012/07/24/jaap-brassers-favorite-powershell-tips-and-tricks/

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx

    https://gallery.technet.microsoft.com/scriptcenter/Get-ChildItemV2-to-list-29291aae

    【讨论】:

    • 我没有尝试 Directory.fullName 但 DirectoryName 仅适用于 PS3。你想让我如何在我的程序中测试 Directory.fullName ?我确实有管道问题
    • 我在答案中添加了另一个 sn-p
    • 好的,它有效,而且速度更快!最后一步是条件,但不会有问题。谢谢你的帮助 !编辑:呃,我们没有解决“唯一”问题,文件不能包含 2 次相同的文件夹。
    • 将列表传递给Select-Object -Unique :-)(最后一个示例已更新以反映这一点)。
    • 这是解决路径过长问题的另一个最新工具:gallery.technet.microsoft.com/scriptcenter/…
    【解决方案2】:

    我也遇到过类似的问题,这样解决的:

    $PathTooLong = @()
    
    Get-ChildItem -LiteralPath $Path -Recurse -ErrorVariable +e -ErrorAction SilentlyContinue
    
    $e | where {$_.Exception -like 'System.IO.PathTooLongException*'} | ForEach-Object {
        $PathTooLong += $_.TargetObject
        $Global:Error.Remove($_)
    }
    
    $PathTooLong
    

    在每条路径过长或 PowerShell 引擎无法处理的情况下,Get-ChildItem 都会抛出错误。此错误保存在上例中称为eErrorVariable 中。

    当所有错误都收集在$e 中时,您可以通过检查错误Exception 中的字符串System.IO.PathTooLongException 来过滤掉您需要的错误。

    希望对你有所帮助。

    【讨论】:

      【解决方案3】:

      您不能使用get-childitem 列出大于 Windows 字符限制的路径。

      您有几种选择。尝试使用“Alphafs”之类的外部库,或者您可以使用 robocopy。 Boe Prox 有一个使用 robocopy 的脚本,它可以在 technet 上找到,但我不确定它是否适用于 PSV2。不管怎样,你可以试一试。

      【讨论】:

      • 好吧,实际上程序似乎在工作,唯一的问题是很多文件夹被多次写入
      • program 是指我链接的 technet 脚本吗?如果是这样,只需使用 select-object -unique 就像 @sodawillow 建议的那样..
      • 我的意思是get-childitem,现在我在等着看select-object -unique 是否可以工作
      • get-childitem 肯定不会使用超过 260 个字符的路径...但是如果它对您有用,那么我只能说很棒:)...我现在走了..好运气。
      猜你喜欢
      • 2020-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多