从文件中选择目录

时间:2015-12-11 07:34:29

标签: windows powershell

我需要我的程序给我每个包含超出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。

3 个答案:

答案 0 :(得分:0)

>您正在构建的工具可能无法报告超出限制的路径,因为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

答案 1 :(得分:0)

您无法使用get-childitem列出大于Windows字符数限制的路径。

您有几种选择。尝试使用' Alphafs'等外部库。或者你可以使用robocopy。 Boe Prox有一个利用robocopy的脚本,可以technet使用,但我不确定它是否适用于PSV2。无论如何,你可以尝试一下。

答案 2 :(得分:-1)

我遇到了类似的问题,并解决了这个问题:

$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都会抛出错误。此错误保存在上例中名为ErrorVariable的{​​{1}}中。

如果在e中收集了所有错误,您可以通过检查字符串$e的错误Exception来过滤掉您需要的错误。

希望它可以帮助你。