web-dev-qa-db-ja.com

Windowsでパスの長さが260文字を超えるファイルを見つけるにはどうすればよいですか?

XP windowsスクリプトでxcopyを使用して、ディレクトリを再帰的にコピーしています。 「メモリ不足」エラーが表示され続けます。これは、コピーしようとしているファイルのパスが長すぎるためです。パスの長さは簡単に減らすことができますが、残念ながらパスの長さの制限に違反しているファイルを特定することはできません。コピーされたファイルは標準出力(ログファイルにリダイレクトします)に出力されますが、エラーメッセージは端末に出力されるため、エラーがどのディレクトリに割り当てられているかを正確に把握することもできません。 。

75
WestHamster

dir /s /b > out.txtを実行し、位置260にガイドを追加します

PowerShellでcmd /c dir /s /b |? {$_.length -gt 260}

96
rerun

この目的で パス長チェッカーツール を作成しました。これは、指定されたディレクトリ内のすべてのファイルとディレクトリのパス長を確認するために使用できる、無料の素敵なGUIアプリです。

また、ファイルとディレクトリの長さを取得するための 単純なPowerShellスクリプトについて記述およびブログ化 を行いました。ファイルの長さとパスを出力し、オプションでコンソールにも書き込みます。特定の長さのみのファイルの表示に限定されず(簡単に変更できます)、長さの降順でファイルを表示するため、どのパスがしきい値を超えているかを簡単に確認できます。ここにあります:

$pathToScan = "C:\Some Folder"  # The path to scan and the the lengths for (sub-directories will be scanned as well).
$outputFilePath = "C:\temp\PathLengths.txt" # This must be a file in a directory that exists and does not require admin rights to write to.
$writeToConsoleAsWell = $true   # Writing to the console will be much slower.

# Open a new file stream (Nice and fast) and write all the paths and their lengths to it.
$outputFileDirectory = Split-Path $outputFilePath -Parent
if (!(Test-Path $outputFileDirectory)) { New-Item $outputFileDirectory -ItemType Directory }
$stream = New-Object System.IO.StreamWriter($outputFilePath, $false)
Get-ChildItem -Path $pathToScan -Recurse -Force | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}} | Sort-Object -Property FullNameLength -Descending | ForEach-Object {
    $filePath = $_.FullName
    $length = $_.FullNameLength
    $string = "$length : $filePath"

    # Write to the Console.
    if ($writeToConsoleAsWell) { Write-Host $string }

    #Write to the file.
    $stream.WriteLine($string)
}
$stream.Close()
28
deadlydog

最も単純なソリューションの改良版として、Powershellをインストールできない、またはインストールしたくない場合は、次を実行します。

dir /s /b | sort /r /+261 > out.txt

または(高速):

dir /s /b | sort /r /+261 /o out.txt

また、260より長い行はリストの先頭になります。 SORT列パラメーターに1を追加する必要があることに注意してください(/ + n)。

22
Chungalin

ここでは、PowerShellを使用する他の適切な回答に代わるものを作成しましたが、私もリストをファイルに保存します。他の誰かがそのようなものを望んでいる場合に備えて、ここで共有します。

警告:コードは、現在の作業ディレクトリの「longfilepath.txt」を上書きします。すでに持っている可能性は低いですが、念のために!

意図的に単一行でそれを望んでいた:

Out-File longfilepath.txt ; cmd /c "dir /b /s /a" | ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}

詳細な手順:

  1. PowerShellを実行する
  2. ファイルパスの長さを確認したいディレクトリに移動します(C:動作します)
  3. コードをコピーして貼り付ける[右クリックしてPowerShellで貼り付けるか、Alt + Space> E> P]
  4. 完了するまで待ってから、ファイルを表示します:cat longfilepath.txt | sort

説明:

Out-File longfilepath.txt ; – 'longfilepath.txt'というタイトルの空のファイルを作成(または上書き)します。コマンドを区切るセミコロン。

cmd /c "dir /b /s /a" | – PowerShellでdirコマンド/aを実行して、隠しファイルを含むすべてのファイルを表示します。 |からパイプへ。

ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}} –各行($ _と表示)で、長さが250を超える場合、その行をファイルに追加します。

3
Rani Kheir

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

Get-ChildItem –Force –Recurse –ErrorAction SilentlyContinue –ErrorVariable AccessDenied

最初の部分は、これとサブフォルダーを繰り返し処理するだけです。 -ErrorVariable AccessDeniedを使用することは、問題のある項目をパワーシェル変数AccessDeniedにプッシュすることを意味します。

その後、変数を次のようにスキャンできます

$AccessDenied |
Where-Object { $_.Exception -match "must be less than 260 characters" } |
ForEach-Object { $_.TargetObject }

これらのファイルを気にしない場合(場合によっては適用可能)、単に-ErrorVariable AccessDenied部分をドロップします。

2
Jonno

stderrをリダイレクトできます。

詳細な説明 ここ 、ただし次のようなコマンドがあります:

MyCommand >log.txt 2>errors.txt

探しているデータを取得する必要があります。

また、トリックとして、パスの先頭に\\?\msdn )が付いている場合、Windowsはその制限をバイパスします

長いパスで始まるルートまたは宛先がある場合の別のトリック、おそらくSUBSTが役立ちます:

SUBST Q: "C:\Documents and Settings\MyLoginName\My Documents\MyStuffToBeCopied"
Xcopy Q:\ "d:\Where it needs to go" /s /e
SUBST Q: /D
2
SeanC

TLPD( "長すぎるパスディレクトリ")は私を救ったプログラムです。非常に使いやすい:

https://sourceforge.net/projects/tlpd/

1
pollaris