Saving 'tree /f /a" results to a textfile with unicode support

Viewed 74457

I'm trying to use the tree command in a windows commandline to generate a text file listing the contents of a directory but when I pipe the output the unicode characters get stuffed up.

Here is the command I am using:

tree /f /a > output.txt

The results in the console window are fine:

\---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 - 04 Esõben szaladtá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 - 08 Mécsvilág.ogg
        Kátai Tamás - 09 Zúzmara.ogg

But the text file is no good:

\---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 - 04 Esäben szaladt 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 - 08 M‚csvil g.ogg
        K tai Tam s - 09 Z£zmara.ogg

How can I fix this? Ideally the text file would be exactly the same as the output in the console window.

I tried Chris Jester-Young's suggestion (what happened, did you delete it Chris?) of running the command line with the /U switch, it looked like exactly what I needed but it does not appear to work. I have tried opening the file in both VS2008 and notepad and both show the same incorrect characters.

13 Answers

If you output as non-Unicode (which you apparently do), you have to view the text file you create using the same encoding the Console window uses. That's why it looks correct in the console. In some text editors, you can choose an encoding (or "code page") when you open a file. (How to output as Unicode I don't know. cmd /U doesn't do what the documentation says.)

The Console encoding depends on your Windows installation. For me, it's "Western European (DOS)" (or just "MS-DOS") in Microsoft Word.

I decided I had to have a look at tree.com and figure out why it's not respecting the Unicode setting of the console. It turns out that (like many of the command-line file utilities), it uses a library called ulib.dll to do all the printing (specifically, TREE::DisplayName calls WriteString in ulib).

Now, in ulib, the WriteString method is implemented in two classes, SCREEN and STREAM. The SCREEN version uses WriteConsoleW directly, so all the Unicode characters get correctly displayed. The STREAM version converts the Unicode text to one of three different encodings (_UseConsoleConversions ⇒ console codepage (GetConsoleCP), _UseAnsiConversions ⇒ default ANSI codepage, otherwise ⇒ default OEM codepage), and then writes this out. I don't know how to change the conversion mode, and I don't believe the conversion can be disabled.

I've only looked at this briefly, so perhaps more adventurous souls can speak more about it! :-)

XP1's answer is great, but had a minor caveat: the output encoding is UCS2-LE, while I'd prefer UTF8 (smaller filesize, and more widespread).

After a lot of searching and head scratching, I can finally present you the following command, that produces an UTF8-BOM file:

PowerShell -Command "TREE /F | Out-File output.txt -Encoding utf8"

If the output filename has spaces:

PowerShell -Command "TREE /F | Out-File ""output file.txt"" -Encoding utf8"

Many thanks to this article: https://www.kongsli.net/2012/04/20/powershell-gotchas-redirect-to-file-encodes-in-unicode/


Also, personally I have created the following files in my 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"

Finally, instead of tree > output.txt I just do xtree output.txt

I used this method to catalog nearly 100 SDRAM and USB flashdrives and it worked fine.

From within DOS....

C:\doskey [enter] {to enable handy keyboard shortcuts}

C:\tree j:\ >> d:\MyCatalog.txt /a [enter] {j:= is my USB drive ; d:= is where I want catalog ; /a = see other postings on this page}

XP1's answer is great, or at least the best here—tree command just can't handle some symbols even with this treatment.

However, at least on my setup, this script will generate trees missing the final line. While I'm unsure why exactly this happens, it can be fixed by modifying function listTree to look like this:

function listTree {
    tree /f
    echo .
}

Where echo . prints a line for PowerShell to cannibalize freely. This sacrifice sates it and the tree is output in entirety.

Related