Windows でパスの長さが 260 文字を超えるファイルを検索するにはどうすればよいですか?
-
12-12-2019 - |
質問
XP Windows スクリプトで xcopy を使用してディレクトリを再帰的にコピーしています。「メモリ不足」エラーが繰り返し発生します。これは、コピーしようとしているファイルのパスが長すぎることが原因であると理解しています。パスの長さは簡単に減らすことができますが、残念ながらどのファイルがパスの長さの制限に違反しているかを特定することはできません。コピーされたファイルは標準出力 (ログ ファイルにリダイレクトしています) に出力されますが、エラー メッセージは端末に出力されるため、どのディレクトリに対してエラーが発生しているのかさえわかりません。 。
解決
dir /s /b > out.txt
を実行してから、260
cmd /c dir /s /b |? {$_.length -gt 260}
他のヒント
私はパス長チェッカーツールこの目的のためのPath Length Checker Tool です。特定のディレクトリ内のすべてのファイルとディレクトリのパス長を見るために使用できます。
私はまた単純な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()
. 最も簡単な解決策の洗練として、そしてあなたがPowerShellをインストールすることができないかどうかをuptしたくない場合は、
dir /s /b | sort /r /+261 > out.txt
.
または(速い):
dir /s /b | sort /r /+261 /o out.txt
.
と260以上の行はリストの上部に到達します。列パラメータ(/ + N)をソートするには1を追加する必要があります。
ここでPowerShellを使用する他の良い回答の代替案を作成しましたが、私の回答ではリストをファイルに保存することもできます。他の誰かがそのようなものを必要としている場合に備えて、ここで共有します。
警告: コードにより、現在の作業ディレクトリの「longfilepath.txt」が上書きされます。すでに持っている可能性は低いと思いますが、念のため!
意図的に 1 行で記述したいと考えました。
Out-File longfilepath.txt ; cmd /c "dir /b /s /a" | ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}
詳細な手順:
- PowerShell を実行する
- ファイルパスの長さを確認するディレクトリに移動します (C:作品)
- コードをコピーして貼り付けます [右クリックして PowerShell に貼り付けるか、Alt + Space > E > P]
- 完了するまで待ってから、ファイルを表示します。
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 を超える場合は、その行をファイルに追加します。
標準エラー出力をリダイレクトできます。
詳しい説明 ここ, ですが、次のようなコマンドがあります。
MyCommand >log.txt 2>errors.txt
探しているデータを取得する必要があります。
また、パスの先頭に \\?\
(msdn)
長いパスで始まるルートまたは宛先がある場合のもう 1 つのトリックは、おそらく SUBST
役立ちます:
SUBST Q: "C:\Documents and Settings\MyLoginName\My Documents\MyStuffToBeCopied"
Xcopy Q:\ "d:\Where it needs to go" /s /e
SUBST Q: /D
から http://www.powershellmagase.com/2012/07/24/jaap-rassers-favorite-powershell-tips-and-tricks/ :
Get-ChildItem –Force –Recurse –ErrorAction SilentlyContinue –ErrorVariable AccessDenied
.
最初の部分は、このとサブフォルダを介して反復するだけです。-ErrorVariable AccessDenied
を使用すると、問題のあるアイテムをPowerShell変数AccessDenied
に押し込みます。
その後、
のような変数をスキャンすることができます。$AccessDenied |
Where-Object { $_.Exception -match "must be less than 260 characters" } |
ForEach-Object { $_.TargetObject }
.
これらのファイルを気にしない場合(場合によっては適用可能である場合があります)、-ErrorVariable AccessDenied
部分を削除するだけです。
tlpd( "long path directory")は私を保存したプログラムです。 非常に使いやすい:
nofollow noreferrer"> https://sourceforge.net/projects/tlpd/
260より大きいパスの場合:
Get-ChildItem | Where-Object {$_.FullName.Length -gt 260}
.
例14文字の例:
パスの長さを表示するには:
Get-ChildItem | Select-Object -Property FullName, @{Name="FullNameLength";Expression={($_.FullName.Length)}
.
14より大きいパスを取得する:
Get-ChildItem | Where-Object {$_.FullName.Length -gt 14}
.
スクリーンショット:
10より大きいファイル名の場合:
Get-ChildItem | Where-Object {$_.PSChildName.Length -gt 10}
.
スクリーンショット: