Windowsコマンドラインでtreeコマンドを使用して、ディレクトリの内容をリストしたテキストファイルを生成しようとしていますが、出力をパイプすると、Unicode文字が詰まります。
これが私が使っているコマンドです:
tree /f /a > output.txt
コンソールウィンドウの結果は問題ありません。
\--- Erikaszobája cover.jpg Erikaszobája.m3u KátaiTamás-01Télvíz.ogg KátaiTamás-02Zölderdõ .ogg カタイタマス-03ルノワールkertje.ogg カタイタマス-04エシュベンシャラダール.ogg カタイタマース-05 kzik azút.ogg カタイタマース- 06Sûrûvölgyektakaród.ogg KátaiTamás-07Õszhozó.ogg KátaiTamás-08Mécsvilág.ogg KátaiTamás-09 Zuzzmara.ogg
しかし、テキストファイルは適切ではありません。
\--- Erika szob ja cover.jpg Erika szob ja.m3u K tai Tam s-01 T‚lv¡z.ogg K tai Tam s-02 Z”lderdä.ogg K tai Tam s-03 Renoir kertje.ogg K tai Tam s-04Esäbenszaladt l.ogg K tai Tam s-05 µzik az£t.ogg K tai Tam s-06 S–r– v” lgyek takar¢d.ogg K tai Tam s-07åszhoz¢.ogg K tai Tam s-08Mâcsvilg.ogg K tai Tam s-09 Z£zmara.ogg
どうすれば修正できますか?理想的には、テキストファイルはコンソールウィンドウの出力とまったく同じです。
/ Jスイッチを使用してコマンドラインを実行するというChris Jester-Youngの提案(何が起こったのですか、Chrisを削除しましたか?)を試してみました。 VS2008とメモ帳の両方でファイルを開こうとしましたが、どちらも同じ不正な文字が表示されています。
誰かがすでにこれを試しました:
tree /f /a |clip
メモ帳を開き、Ctrl + V、Unicodeをサポートするoutput.txtとしてメモ帳に保存しますか?
非ユニコードとして出力する場合(明らかにそうです)、コンソールウィンドウが使用するのと同じエンコーディングを使用して作成したテキストファイルを表示する必要があります。そのため、コンソールでは正しく表示されます。一部のテキストエディターでは、ファイルを開くときにエンコード(または「コードページ」)を選択できます。 (Unicodeとして出力する方法はわかりません。cmd/ Uは、ドキュメントに書かれていることを実行しません。)
コンソールのエンコーディングは、Windowsのインストールによって異なります。私にとっては、Microsoft Wordの「西ヨーロッパ(DOS)」(または単に「MS-DOS」)です。
PowerShellを使用します。
powershell -command "tree /f > tree.txt"
create.ps1
:
mkdir "Erika szobája"
$null | Set-Content "Erika szobája/cover.jpg"
$null | Set-Content "Erika szobája/Erika szobája.m3u"
$null | Set-Content "Erika szobája/Kátai Tamás - 01 Télvíz.ogg"
$null | Set-Content "Erika szobája/Kátai Tamás - 02 Zölderdõ.ogg"
$null | Set-Content "Erika szobája/Kátai Tamás - 03 Renoir kertje.ogg"
$null | Set-Content "Erika szobája/Kátai Tamás - 04 Esõben szaladtál.ogg"
$null | Set-Content "Erika szobája/Kátai Tamás - 05 Ázik az út.ogg"
$null | Set-Content "Erika szobája/Kátai Tamás - 06 Sûrû völgyek takaród.ogg"
$null | Set-Content "Erika szobája/Kátai Tamás - 07 Õszhozó.ogg"
$null | Set-Content "Erika szobája/Kátai Tamás - 08 Mécsvilág.ogg"
$null | Set-Content "Erika szobája/Kátai Tamás - 09 Zúzmara.ogg"
出力:
tree.txt
:
Folder PATH listing
Volume serial number is 00000000 0000:0000
C:.
│ create.ps1
│ tree.txt
│
└───Erika szobája
cover.jpg
Erika szobája.m3u
Kátai Tamás - 01 Télvíz.ogg
Kátai Tamás - 02 Zölderdo.ogg
Kátai Tamás - 03 Renoir kertje.ogg
Kátai Tamás - 04 Esoben szaladtál.ogg
Kátai Tamás - 05 Azik az út.ogg
Kátai Tamás - 06 Sûrû völgyek takaród.ogg
Kátai Tamás - 07 Oszhozó.ogg
Kátai Tamás - 08 Mécsvilág.ogg
Kátai Tamás - 09 Zúzmara.ogg
$null | Set-Content "欲速则不达.txt"
$null | Set-Content "爱不是占有,是欣赏.txt"
$null | Set-Content "您先请是礼貌.txt"
$null | Set-Content "萝卜青菜,各有所爱.txt"
$null | Set-Content "广交友,无深交.txt"
$null | Set-Content "一见钟情.txt"
$null | Set-Content "山雨欲来风满楼.txt"
$null | Set-Content "悪妻は百年の不作。.txt"
$null | Set-Content "残り物には福がある。.txt"
$null | Set-Content "虎穴に入らずんば虎子を得ず。.txt"
$null | Set-Content "夏炉冬扇.txt"
$null | Set-Content "花鳥風月.txt"
$null | Set-Content "起死回生.txt"
$null | Set-Content "自業自得.txt"
$null | Set-Content "아는 길도 물어가라.txt"
$null | Set-Content "빈 수레가 요란하다.txt"
$null | Set-Content "방귀뀐 놈이 성낸다.txt"
$null | Set-Content "뜻이 있는 곳에 길이 있다.txt"
$null | Set-Content "콩 심은데 콩나고, 팥 심은데 팥난다.txt"
彼の answer から、@ Chris Jester-Youngはこう書いています:
現在、
ulib
では、WriteString
メソッドがSCREEN
とSTREAM
の2つのクラスで実装されています。SCREEN
バージョンはWriteConsoleW
を直接使用するため、すべてのUnicode文字が正しく表示されます。STREAM
バージョンは、Unicodeテキストを3つの異なるエンコーディング(_UseConsoleConversions
⇒コンソールコードページ(GetConsoleCP
)、_UseAnsiConversions
⇒デフォルトのANSIコードページ、それ以外の場合⇒デフォルトのOEMコードページ)、そしてこれを書き出します。
つまり、ストリームからの文字の取得に依存することはできません。ファイルのリダイレクトは機能しません。 Unicode文字を取得するには、コンソールに書き込む必要があります。
回避策、つまりハックは、ツリーをコンソールに書き込み、バッファをファイルにダンプすることです。
エクスプローラでディレクトリを右クリックしたときにツリーのコンテキストメニューを追加するスクリプトを作成しました。同じディレクトリにファイルを保存してから、Install list menu.bat
インストールする管理者として。
Install list menu.bat
@echo on
regedit /s "List files.reg"
copy "List.ps1" "%SystemRoot%"
pause
List files.reg
Windows Registry Editor Version 5.00
; Directory.
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\Shell\List]
"MUIVerb"="List"
"ExtendedSubCommandsKey"="Directory\\ContextMenus\\List"
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\ContextMenus\List\Shell\Files]
"MUIVerb"="Files"
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\ContextMenus\List\Shell\Files\Command]
; powershell -executionPolicy bypass "%SystemRoot%\List.ps1" -type 'files' -directory '%1'
@=hex(2):70,00,6f,00,77,00,65,00,72,00,73,00,68,00,65,00,6c,00,6c,00,20,00,2d,\
00,65,00,78,00,65,00,63,00,75,00,74,00,69,00,6f,00,6e,00,50,00,6f,00,6c,00,\
69,00,63,00,79,00,20,00,62,00,79,00,70,00,61,00,73,00,73,00,20,00,22,00,25,\
00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,\
4c,00,69,00,73,00,74,00,2e,00,70,00,73,00,31,00,22,00,20,00,2d,00,74,00,79,\
00,70,00,65,00,20,00,27,00,66,00,69,00,6c,00,65,00,73,00,27,00,20,00,2d,00,\
64,00,69,00,72,00,65,00,63,00,74,00,6f,00,72,00,79,00,20,00,27,00,25,00,31,\
00,27,00,00,00
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\ContextMenus\List\Shell\FilesRecursively]
"MUIVerb"="Files recursively"
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\ContextMenus\List\Shell\FilesRecursively\Command]
; powershell -executionPolicy bypass "%SystemRoot%\List.ps1" -type 'filesRecursively' -directory '%1'
@=hex(2):70,00,6f,00,77,00,65,00,72,00,73,00,68,00,65,00,6c,00,6c,00,20,00,2d,\
00,65,00,78,00,65,00,63,00,75,00,74,00,69,00,6f,00,6e,00,50,00,6f,00,6c,00,\
69,00,63,00,79,00,20,00,62,00,79,00,70,00,61,00,73,00,73,00,20,00,22,00,25,\
00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,\
4c,00,69,00,73,00,74,00,2e,00,70,00,73,00,31,00,22,00,20,00,2d,00,74,00,79,\
00,70,00,65,00,20,00,27,00,66,00,69,00,6c,00,65,00,73,00,52,00,65,00,63,00,\
75,00,72,00,73,00,69,00,76,00,65,00,6c,00,79,00,27,00,20,00,2d,00,64,00,69,\
00,72,00,65,00,63,00,74,00,6f,00,72,00,79,00,20,00,27,00,25,00,31,00,27,00,\
00,00
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\ContextMenus\List\Shell\Tree]
"MUIVerb"="Tree"
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\ContextMenus\List\Shell\Tree\Command]
; powershell -executionPolicy bypass "%SystemRoot%\List.ps1" -type 'tree' -directory '%1'
@=hex(2):70,00,6f,00,77,00,65,00,72,00,73,00,68,00,65,00,6c,00,6c,00,20,00,2d,\
00,65,00,78,00,65,00,63,00,75,00,74,00,69,00,6f,00,6e,00,50,00,6f,00,6c,00,\
69,00,63,00,79,00,20,00,62,00,79,00,70,00,61,00,73,00,73,00,20,00,22,00,25,\
00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,\
4c,00,69,00,73,00,74,00,2e,00,70,00,73,00,31,00,22,00,20,00,2d,00,74,00,79,\
00,70,00,65,00,20,00,27,00,74,00,72,00,65,00,65,00,27,00,20,00,2d,00,64,00,\
69,00,72,00,65,00,63,00,74,00,6f,00,72,00,79,00,20,00,27,00,25,00,31,00,27,\
00,00,00
; Directory background.
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\Background\Shell\List]
"MUIVerb"="List"
"ExtendedSubCommandsKey"="Directory\\Background\\ContextMenus\\List"
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\Background\ContextMenus\List\Shell\Files]
"MUIVerb"="Files"
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\Background\ContextMenus\List\Shell\Files\Command]
; powershell -executionPolicy bypass "%SystemRoot%\List.ps1" -type 'files' -directory '%V'
@=hex(2):70,00,6f,00,77,00,65,00,72,00,73,00,68,00,65,00,6c,00,6c,00,20,00,2d,\
00,65,00,78,00,65,00,63,00,75,00,74,00,69,00,6f,00,6e,00,50,00,6f,00,6c,00,\
69,00,63,00,79,00,20,00,62,00,79,00,70,00,61,00,73,00,73,00,20,00,22,00,25,\
00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,\
4c,00,69,00,73,00,74,00,2e,00,70,00,73,00,31,00,22,00,20,00,2d,00,74,00,79,\
00,70,00,65,00,20,00,27,00,66,00,69,00,6c,00,65,00,73,00,27,00,20,00,2d,00,\
64,00,69,00,72,00,65,00,63,00,74,00,6f,00,72,00,79,00,20,00,27,00,25,00,56,\
00,27,00,00,00
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\Background\ContextMenus\List\Shell\FilesRecursively]
"MUIVerb"="Files recursively"
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\Background\ContextMenus\List\Shell\FilesRecursively\Command]
; powershell -executionPolicy bypass "%SystemRoot%\List.ps1" -type 'filesRecursively' -directory '%V'
@=hex(2):70,00,6f,00,77,00,65,00,72,00,73,00,68,00,65,00,6c,00,6c,00,20,00,2d,\
00,65,00,78,00,65,00,63,00,75,00,74,00,69,00,6f,00,6e,00,50,00,6f,00,6c,00,\
69,00,63,00,79,00,20,00,62,00,79,00,70,00,61,00,73,00,73,00,20,00,22,00,25,\
00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,\
4c,00,69,00,73,00,74,00,2e,00,70,00,73,00,31,00,22,00,20,00,2d,00,74,00,79,\
00,70,00,65,00,20,00,27,00,66,00,69,00,6c,00,65,00,73,00,52,00,65,00,63,00,\
75,00,72,00,73,00,69,00,76,00,65,00,6c,00,79,00,27,00,20,00,2d,00,64,00,69,\
00,72,00,65,00,63,00,74,00,6f,00,72,00,79,00,20,00,27,00,25,00,56,00,27,00,\
00,00
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\Background\ContextMenus\List\Shell\Tree]
"MUIVerb"="Tree"
[HKEY_LOCAL_MACHINE\Software\Classes\Directory\Background\ContextMenus\List\Shell\Tree\Command]
; powershell -executionPolicy bypass "%SystemRoot%\List.ps1" -type 'tree' -directory '%V'
@=hex(2):70,00,6f,00,77,00,65,00,72,00,73,00,68,00,65,00,6c,00,6c,00,20,00,2d,\
00,65,00,78,00,65,00,63,00,75,00,74,00,69,00,6f,00,6e,00,50,00,6f,00,6c,00,\
69,00,63,00,79,00,20,00,62,00,79,00,70,00,61,00,73,00,73,00,20,00,22,00,25,\
00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,\
4c,00,69,00,73,00,74,00,2e,00,70,00,73,00,31,00,22,00,20,00,2d,00,74,00,79,\
00,70,00,65,00,20,00,27,00,74,00,72,00,65,00,65,00,27,00,20,00,2d,00,64,00,\
69,00,72,00,65,00,63,00,74,00,6f,00,72,00,79,00,20,00,27,00,25,00,56,00,27,\
00,00,00
List.ps1
function sortNaturally {
[Regex]::replace($_, '\d+', {
$args[0].value.padLeft(20)
})
}
function writeList {
param(
[parameter(mandatory = $true)]
[string] $text = $null
)
$filePath = "$env:temp\List.txt"
$text > "$filePath"
notepad "$filePath" | out-null
del "$filePath"
}
function listFiles {
param(
[switch] $recurse = $false
)
get-childItem -name -recurse:$recurse -force | sort-object $function:sortNaturally | out-string
}
function listTree {
tree /f
}
function getBufferText {
$rawUi = $Host.ui.rawUi
$width = [Math]::max([Math]::max($rawUi.bufferSize.width, $rawUi.windowSize.width) - 1, 0)
$height = [Math]::max($rawUi.cursorPosition.y - 1, 0)
$lines = new-object System.Text.StringBuilder
$characters = new-object System.Text.StringBuilder
for ($h = 0; $h -lt $height; $h += 1) {
$rectangle = new-object System.Management.Automation.Host.Rectangle 0, $h, $width, $h
$buffer = $rawUi.getBufferContents($rectangle)
for ($w = 0; $w -lt $width; $w += 1) {
$cell = $buffer[0, $w]
$character = $cell.character
$characters.append($character) | out-null
}
$lines.appendLine($characters.toString()) | out-null
$characters.length = 0
}
$lines.toString() -replace '[ \0]*\r?\n', "`r`n"
}
function main {
param(
[parameter(mandatory = $true)]
[string] $type = $null,
[parameter(mandatory = $true)]
[string] $directory = $null
)
$outputEncoding = [Text.UTF8Encoding]::UTF8
[Console]::outputEncoding = [Text.UTF8Encoding]::UTF8
$PSDefaultParameterValues['out-file:encoding'] = 'utf8'
set-location -literalPath "$directory"
$typeFunction = @{
'files' = { writeList -text $(listFiles) };
'filesRecursively' = { writeList -text $(listFiles -recurse) };
'tree' = {
listTree
writeList -text $(getBufferText)
}
}
&($typeFunction.get_item($type))
}
main @args
これにより、結果がデスクトップにASCII(American Standard Code for Information Interchange))として保存されます。ASCII\ ANSIは、すべての国際文字または拡張文字を認識しません。
tree /f > ascii.txt
これは、ASCIIテキストをUnicodeに変換します(/ cは実際のコマンドの前に置く必要があります):
cmd /u /c type ascii.txt > unicode.txt
それでは、ASCIIファイルを一時ファイルと見なして削除しないのはなぜですか。
del ascii.txt
すべてを1行に入れる必要がある場合は、次のように使用できます。
tree /f > ascii.txt & cmd.exe /u /c type ascii.txt > unicode.txt & del ascii.txt
tree.com
を見て、コンソールのUnicode設定が考慮されていない理由を理解する必要があると判断しました。 (多くのコマンドラインファイルユーティリティと同様に)ulib.dll
と呼ばれるライブラリを使用してすべての印刷を行うことがわかります(具体的には、TREE::DisplayName
がWriteString
を呼び出してulib
)。
現在、ulib
では、WriteString
メソッドがSCREEN
とSTREAM
の2つのクラスで実装されています。 SCREEN
バージョンはWriteConsoleW
を直接使用するため、すべてのUnicode文字が正しく表示されます。 STREAM
バージョンは、Unicodeテキストを3つの異なるエンコーディングのいずれかに変換します(_UseConsoleConversions
⇒コンソールコードページ(GetConsoleCP
)、_UseAnsiConversions
⇒デフォルトのANSIコードページ、それ以外の場合⇒デフォルトのOEMコードページ)、そしてこれを書き出します。変換モードを変更する方法がわかりません。変換を無効にできるとは思いません。
私はこれを簡単に見てきただけなので、おそらくより冒険的な魂がそれについてもっと話すことができます! :-)
短い答えはできないであり、これはtree.com
は、Windows 7でもANSIアプリケーションです。
唯一の解決策は、独自のtree
実装を作成することです。また、Microsoftにバグを報告することもできますが、彼らがまだそれに気付いていないのではないでしょうか。
あなたが試すことができます
tree /A > output.txt
CMD行とは異なって見えますが、それでも問題ありません。 :P
これは私のために働きました:
tree /f /a > %temp%\Listing >> files.txt
XP1の答えは素晴らしいですが、軽微な注意点がありました。出力エンコーディングはUCS2-LEですが、私はUTF8(ファイルサイズが小さく、広く普及している)を好みます。
たくさんの検索と頭のスクラッチの後、最終的にUTF8-BOMファイルを生成する次のコマンドを提示できます:
PowerShell -Command "TREE /F | Out-File output.txt -Encoding utf8"
出力ファイル名にスペースがある場合:
PowerShell -Command "TREE /F | Out-File ""output file.txt"" -Encoding utf8"
この記事に感謝: https://www.kongsli.net/2012/04/20/powershell-gotchas-redirect-to-file-encodes-in-unicode/
また、個人的には、PATHに次のファイルを作成しました。
xtree.cmd
:
@IF [%1]==[] @(
ECHO You have to specify an output file.
GOTO :EOF
)
@PowerShell -Command "TREE | Out-File %1 -Encoding utf8"
xtreef.cmd
:
@IF [%1]==[] @(
ECHO You have to specify an output file.
GOTO :EOF
)
@PowerShell -Command "TREE /F | Out-File %1 -Encoding utf8"
最後に、tree > output.txt
するだけですxtree output.txt
私はこの方法を使用して、ほぼ100のSDRAMおよびUSBフラッシュドライブをカタログ化しましたが、正常に機能しました。
DOS内から...
C:\ doskey [Enter] {便利なキーボードショートカットを有効にするため}
C:\ tree j:\ >> d:\ MyCatalog.txt/a [入力] {j:=は私のUSBドライブです; d:=はカタログが必要な場所です。/a =このページの他の投稿を参照}
コンソールに出力し(tree
だけ)、コンソールからコピーする(システムメニュー->編集->マーク)と、すべての非ASCII文字が変換されずに、コンソールでそのまま出力を取得することに成功しました、すべて選択、Enter)。コンソールのプロパティ(システムメニュー->プロパティ)で、ファイル/フォルダーの数に応じて、コンソールのバッファーサイズを事前に増やす必要があります。他の方法ではうまくいきませんでした。以前の投稿で述べたtree|clip
は、非ASCII文字をtree>file.txt
と同じASCII文字に変換します。
Take Command Console を使用して、ツリーコマンドの非ASCII文字をファイルに適切に出力できました。
TCCで「オプション」と入力し、最初のタブで「Unicode出力」を選択します。次に、単に実行します
tree /f /a > output.txt