web-dev-qa-db-ja.com

「ツリー/ f / a」の結果をUnicodeサポート付きのテキストファイルに保存する

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とメモ帳の両方でファイルを開こうとしましたが、どちらも同じ不正な文字が表示されています。

27
Paul Batum

誰かがすでにこれを試しました:

tree /f /a |clip

メモ帳を開き、Ctrl + V、Unicodeをサポートするoutput.txtとしてメモ帳に保存しますか?

44
Ricardo Bohner

非ユニコードとして出力する場合(明らかにそうです)、コンソールウィンドウが使用するのと同じエンコーディングを使用して作成したテキストファイルを表示する必要があります。そのため、コンソールでは正しく表示されます。一部のテキストエディターでは、ファイルを開くときにエンコード(または「コードページ」)を選択できます。 (Unicodeとして出力する方法はわかりません。cmd/ Uは、ドキュメントに書かれていることを実行しません。)

コンソールのエンコーディングは、Windowsのインストールによって異なります。私にとっては、Microsoft Wordの「西ヨーロッパ(DOS)」(または単に「MS-DOS」)です。

11
bzlm

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

編集:

パワーユーザー向けの強化および改善されたバージョン

List tree menu working with Unicode

テストケース:

$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メソッドがSCREENSTREAMの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
10
XP1

これにより、結果がデスクトップに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
5
Ricardo Bohner

tree.comを見て、コンソールのUnicode設定が考慮されていない理由を理解する必要があると判断しました。 (多くのコマンドラインファイルユーティリティと同様に)ulib.dllと呼ばれるライブラリを使用してすべての印刷を行うことがわかります(具体的には、TREE::DisplayNameWriteStringを呼び出してulib)。

現在、ulibでは、WriteStringメソッドがSCREENSTREAMの2つのクラスで実装されています。 SCREENバージョンはWriteConsoleWを直接使用するため、すべてのUnicode文字が正しく表示されます。 STREAMバージョンは、Unicodeテキストを3つの異なるエンコーディングのいずれかに変換します(_UseConsoleConversions⇒コンソールコードページ(GetConsoleCP)、_UseAnsiConversions⇒デフォルトのANSIコードページ、それ以外の場合⇒デフォルトのOEMコードページ)、そしてこれを書き出します。変換モードを変更する方法がわかりません。変換を無効にできるとは思いません。

私はこれを簡単に見てきただけなので、おそらくより冒険的な魂がそれについてもっと話すことができます! :-)

5

短い答えはできないであり、これはtree.comは、Windows 7でもANSIアプリケーションです。

唯一の解決策は、独自のtree実装を作成することです。また、Microsoftにバグを報告することもできますが、彼らがまだそれに気付いていないのではないでしょうか。

3
sorin

あなたが試すことができます

tree /A > output.txt

CMD行とは異なって見えますが、それでも問題ありません。 :P

3
Kenn

これは私のために働きました:

tree /f /a > %temp%\Listing >> files.txt
2
Chris

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

0
Gras Double

私はこの方法を使用して、ほぼ100のSDRAMおよびUSBフラッシュドライブをカタログ化しましたが、正常に機能しました。

DOS内から...

C:\ doskey [Enter] {便利なキーボードショートカットを有効にするため}

C:\ tree j:\ >> d:\ MyCatalog.txt/a [入力] {j:=は私のUSBドライブです; d:=はカタログが必要な場所です。/a =このページの他の投稿を参照}

0
guest

コンソールに出力し(treeだけ)、コンソールからコピーする(システムメニュー->編集->マーク)と、すべての非ASCII文字が変換されずに、コンソールでそのまま出力を取得することに成功しました、すべて選択、Enter)。コンソールのプロパティ(システムメニュー->プロパティ)で、ファイル/フォルダーの数に応じて、コンソールのバッファーサイズを事前に増やす必要があります。他の方法ではうまくいきませんでした。以前の投稿で述べたtree|clipは、非ASCII文字をtree>file.txtと同じASCII文字に変換します。

0
Miguel

Take Command Console を使用して、ツリーコマンドの非ASCII文字をファイルに適切に出力できました。

TCCで「オプション」と入力し、最初のタブで「Unicode出力」を選択します。次に、単に実行します

tree /f /a > output.txt
0
user1959451