XP windowsスクリプトでxcopyを使用して、ディレクトリを再帰的にコピーしています。 「メモリ不足」エラーが表示され続けます。これは、コピーしようとしているファイルのパスが長すぎるためです。パスの長さは簡単に減らすことができますが、残念ながらパスの長さの制限に違反しているファイルを特定することはできません。コピーされたファイルは標準出力(ログファイルにリダイレクトします)に出力されますが、エラーメッセージは端末に出力されるため、エラーがどのディレクトリに割り当てられているかを正確に把握することもできません。 。
dir /s /b > out.txt
を実行し、位置260にガイドを追加します
PowerShellでcmd /c dir /s /b |? {$_.length -gt 260}
この目的で パス長チェッカーツール を作成しました。これは、指定されたディレクトリ内のすべてのファイルとディレクトリのパス長を確認するために使用できる、無料の素敵な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()
最も単純なソリューションの改良版として、Powershellをインストールできない、またはインストールしたくない場合は、次を実行します。
dir /s /b | sort /r /+261 > out.txt
または(高速):
dir /s /b | sort /r /+261 /o out.txt
また、260より長い行はリストの先頭になります。 SORT列パラメーターに1を追加する必要があることに注意してください(/ + n)。
ここでは、PowerShellを使用する他の適切な回答に代わるものを作成しましたが、私もリストをファイルに保存します。他の誰かがそのようなものを望んでいる場合に備えて、ここで共有します。
警告:コードは、現在の作業ディレクトリの「longfilepath.txt」を上書きします。すでに持っている可能性は低いですが、念のために!
意図的に単一行でそれを望んでいた:
Out-File longfilepath.txt ; cmd /c "dir /b /s /a" | ForEach-Object { if ($_.length -gt 250) {$_ | Out-File -append longfilepath.txt}}
詳細な手順:
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を超える場合、その行をファイルに追加します。
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
部分をドロップします。
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
TLPD( "長すぎるパスディレクトリ")は私を救ったプログラムです。非常に使いやすい: