XP Windowsスクリプトでxcopyを使用して、ディレクトリを再帰的にコピーしています。「メモリ不足」エラーが発生し続けます。これは、コピーしようとしているファイルのパスが長すぎるためだと理解しています。パスの長さを簡単に減らすことはできますが、残念ながら、どのファイルがパスの長さの制限に違反しているかを特定できません。コピーされたファイルは標準出力(ログファイルにリダイレクトしています)に出力されますが、エラーメッセージが端末に出力されるため、エラーが発生しているディレクトリを正確に把握することさえできません。 。
9 に答える
を実行して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列パラメーター(/ + 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より大きい場合は、その行をファイルに追加します。
http://www.powershellmagazine.com/2012/07/24/jaap-brassers-favorite-powershell-tips-and-tricks/から:
Get-ChildItem –Force –Recurse –ErrorAction SilentlyContinue –ErrorVariable AccessDenied
最初の部分は、このフォルダーとサブフォルダーを繰り返し処理します。using-ErrorVariable AccessDenied
は、問題のあるアイテムをPowerShell変数にプッシュすることを意味します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(「長すぎるパスディレクトリ」)は私を救ったプログラムです。非常に使いやすい:
狂ったように、この質問はまだ関連しています。E235が私にベースを与えたけれども、答えのどれも私が望むものを私に全く与えませんでした。また、名前の長さを印刷して、トリミングする必要のある文字数を簡単に確認できるようにします。
Get-ChildItem -Recurse | Where-Object {$_.FullName.Length -gt 260} | %{"{0} : {1}" -f $_.fullname.Length,$_.fullname }
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}
スクリーンショット: