windows 将“tree /f /a”结果保存到支持 unicode 的文本文件中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/138576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Saving 'tree /f /a" results to a textfile with unicode support
提问by Paul Batum
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.
我正在尝试在 Windows 命令行中使用 tree 命令来生成一个列出目录内容的文本文件,但是当我通过管道输出输出时,unicode 字符会被塞满。
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 Rentheitroad 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 Rentheitroad 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.
我尝试了使用 /U 开关运行命令行的 Chris Jester-Young 的建议(发生了什么,你删除它了吗 Chris?),它看起来正是我需要的,但它似乎不起作用。我曾尝试在 VS2008 和记事本中打开文件,但都显示相同的错误字符。
回答by Ricardo Bohner
Have someone already tried this:
有没有人已经尝试过这个:
tree /f /a |clip
Open notepad, ctrl + V, save in notepad as output.txt with unicode support?
打开记事本,ctrl + V,在记事本中保存为支持unicode的output.txt?
回答by bzlm
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.)
如果您输出为非 Unicode(您显然是这样做的),则必须使用与控制台窗口使用的相同编码来查看您创建的文本文件。这就是为什么它在控制台中看起来是正确的。在某些文本编辑器中,您可以在打开文件时选择编码(或“代码页”)。(我不知道如何输出为 Unicode。 cmd /U 没有按照文档说的那样做。)
The Console encoding depends on your Windows installation. For me, it's "Western European (DOS)" (or just "MS-DOS") in Microsoft Word.
控制台编码取决于您的 Windows 安装。对我来说,它是 Microsoft Word 中的“西欧 (DOS)”(或只是“MS-DOS”)。
回答by XP1
Use PowerShell:
使用 PowerShell:
powershell -command "tree /f > tree.txt"
Test case:
测试用例:
create.ps1
:
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 Rentheitroad 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"
Output:
输出:
tree.txt
:
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 Rentheitroad 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
EDIT:
编辑:
Enhanced and improved version for power users
高级用户的增强和改进版本
Test case:
测试用例:
$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"
From his answer, @Chris Jester-Young wrote:
从他的回答中,@Chris Jester-Young 写道:
Now, in
ulib
, theWriteString
method is implemented in two classes,SCREEN
andSTREAM
. TheSCREEN
version usesWriteConsoleW
directly, so all the Unicode characters get correctly displayed. TheSTREAM
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.
现在,在 中
ulib
,该WriteString
方法在两个类中实现,SCREEN
和STREAM
。该SCREEN
版本WriteConsoleW
直接使用 ,因此所有Unicode字符都能正确显示。该STREAM
版本将 Unicode 文本转换为三种不同编码之一(_UseConsoleConversions
? 控制台代码页 (GetConsoleCP
)_UseAnsiConversions
、? 默认 ANSI 代码页,否则为 ? 默认 OEM 代码页),然后将其写出。
This means that we cannot rely on getting the characters from a stream. File redirections won't work. We have to rely on writing to the console to get the Unicode characters.
这意味着我们不能依赖从流中获取字符。文件重定向不起作用。我们必须依靠写入控制台来获取 Unicode 字符。
The workaround, or hack, is to write the tree to the console and then dump the buffer to a file.
解决方法或 hack 是将树写入控制台,然后将缓冲区转储到文件中。
I have written the scripts to add the tree context menu when you right click on directories in Explorer. Save the files in the same directory and then run Install list menu.bat
as administrator to install.
我已经编写了脚本以在您右键单击资源管理器中的目录时添加树上下文菜单。将文件保存在同一目录下,然后Install list menu.bat
以管理员身份运行安装。
Install list menu.bat
Install list menu.bat
@echo on
regedit /s "List files.reg"
copy "List.ps1" "%SystemRoot%"
pause
List files.reg
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
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 '[ tree /f > ascii.txt
]*\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
回答by Ricardo Bohner
This will save the results as ASCII (American Standard Code for Information Interchange) on your desktop, ASCII\ANSI doesn't recognize every international or extended character:
这会将结果保存为 ASCII(美国信息交换标准代码),ASCII\ANSI 不能识别每个国际或扩展字符:
cmd /u /c type ascii.txt > unicode.txt
This will convert your ASCII text to Unicode (/c must precede actual command):
这会将您的 ASCII 文本转换为 Unicode(/c 必须在实际命令之前):
del ascii.txt
So why not just think of the ascii file as a temporary file and delete it?
那么为什么不直接将 ascii 文件视为临时文件并删除它呢?
tree /f > ascii.txt & cmd.exe /u /c type ascii.txt > unicode.txt & del ascii.txt
If you must put all in one line you could use:
如果您必须将所有内容放在一行中,您可以使用:
tree /A > output.txt
回答by Chris Jester-Young
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
).
我决定我必须看看tree.com
并弄清楚为什么它不尊重控制台的 Unicode 设置。事实证明,(像许多的命令行文件工具),它使用一种称为库ulib.dll
来完成所有的印刷(特别是TREE::DisplayName
电话WriteString
的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.
现在,在 中ulib
,该WriteString
方法在两个类中实现,SCREEN
和STREAM
。该SCREEN
版本WriteConsoleW
直接使用,因此所有Unicode字符都能正确显示。该STREAM
版本将 Unicode 文本转换为三种不同编码之一(_UseConsoleConversions
? 控制台代码页 ( GetConsoleCP
) _UseAnsiConversions
、? 默认 ANSI 代码页,否则为 ? 默认 OEM 代码页),然后将其写出。我不知道如何更改转换模式,我不相信可以禁用转换。
I've only looked at this briefly, so perhaps more adventurous souls can speak more about it! :-)
我只是简单地看过这个,所以也许更多冒险的灵魂可以谈论更多!:-)
回答by sorin
The short answer is you cannotand this is because tree.com
is an ANSI application, even on Windows 7.
简短的回答是你不能,这是因为它tree.com
是一个 ANSI 应用程序,即使在 Windows 7 上也是如此。
The only solution is to write your own tree
implementation. Also you could file a bug to Microsoft, but I doubt they are not already aware about it.
唯一的解决方案是编写自己的tree
实现。您也可以向 Microsoft 提交错误,但我怀疑他们还没有意识到这一点。
回答by Kenn
You can try
你可以试试
tree /f /a > %temp%\Listing >> files.txt
Though it looks different from the CMD line, it still could be acceptable. :P
虽然它看起来与 CMD 线不同,但它仍然可以接受。:P
回答by Chris
This worked for me:
这对我有用:
tree /f /a > output.txt
回答by Miguel
I've succeeded getting the output as it is in console, with all non-ascii characters not converted, by outputting to the console (just tree
) and then copying from it (system menu -> Edit -> Mark, selecting all, Enter). Console buffer size should be increased in advance, depending on number files/folders, in the console's properties (system menu -> Properties). Other ways didn't work. tree|clip
, mentioned in an earlier post, converts non-ascii characters to ascii ones the same as tree>file.txt
.
通过输出到控制台(只是tree
)然后从中复制(系统菜单 -> 编辑 -> 标记,全选,回车),我已经成功地获得了控制台中的输出,所有非 ascii 字符都没有转换. 应根据控制台属性(系统菜单 -> 属性)中文件/文件夹的数量提前增加控制台缓冲区大小。其他方法都行不通。tree|clip
,在之前的帖子中提到,将非 ascii 字符转换为 ascii 字符,与tree>file.txt
.
回答by user1959451
I've managed to properly output non-ascii characters from tree command into a file via Take Command Console.
我已经设法通过Take Command Console 将tree 命令中的非 ascii 字符正确输出到文件中。
In TCC type "option" and on first tab select "Unicode output". Then simply run
在 TCC 中输入“选项”并在第一个选项卡上选择“Unicode 输出”。然后简单地运行
##代码##