J'essaie d'utiliser la commande tree dans une ligne de commande Windows pour générer un fichier texte répertoriant le contenu d'un répertoire, mais lorsque je rediffuse la sortie, les caractères unicode sont remplis.
Voici la commande que j'utilise:
tree /f /a > output.txt
Les résultats dans la fenêtre de la console sont corrects:
\--- 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
Mais le fichier texte n'est pas bon:
\--- 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
Comment puis-je réparer cela? Idéalement, le fichier texte devrait être identique à la sortie dans la fenêtre de la console.
J'ai essayé la suggestion de Chris Jester-Young (que s'est-il passé, l'avez-vous supprimée, Chris?) D'exécuter la ligne de commande avec le commutateur/U? J'ai essayé d'ouvrir le fichier à la fois dans VS2008 et dans le Bloc-notes et les deux affichent les mêmes caractères incorrects.
Avez-vous déjà essayé ceci:
tree /f /a |clip
Ouvrez le bloc-notes, ctrl + V, enregistrez-le dans le bloc-notes en tant que output.txt avec le support unicode?
Si vous exportez en mode non-Unicode (ce que vous avez apparemment fait), vous devez afficher le fichier texte créé en utilisant le même codage que celui utilisé par la fenêtre de la console. C'est pourquoi cela semble correct dans la console. Dans certains éditeurs de texte, vous pouvez choisir un codage (ou "page de code") lorsque vous ouvrez un fichier. (Comment sortir en Unicode, je ne sais pas. Cmd/U ne fait pas ce que dit la documentation.)
Le codage de la console dépend de votre installation Windows. Pour moi, c'est "Western European (DOS)" (ou simplement "MS-DOS") dans Microsoft Word.
Utilisez 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"
Sortie:
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"
De sa réponse , @Chris Jester-Young a écrit:
Maintenant, dans
ulib
, la méthodeWriteString
est implémentée en deux classes,SCREEN
etSTREAM
. La versionSCREEN
utiliseWriteConsoleW
directement, afin que tous les caractères Unicode soient correctement enregistrés affiché. La versionSTREAM
convertit le texte Unicode en un trois encodages différents (_UseConsoleConversions
⇒ page de code console (GetConsoleCP
),_UseAnsiConversions
⇒ page de code ANSI par défaut, sinon ⇒ page de code OEM par défaut), puis écrit ceci.
Cela signifie que nous ne pouvons pas compter sur l’obtention des caractères d’un flux. Les redirections de fichiers ne fonctionneront pas. Nous devons nous fier à l’écriture sur la console pour obtenir les caractères Unicode.
La solution de contournement, ou hack, consiste à écrire l'arborescence sur la console, puis à vider le tampon dans un fichier.
J'ai écrit les scripts pour ajouter le menu contextuel de l'arborescence lorsque vous cliquez avec le bouton droit sur des répertoires dans Explorer. Enregistrez les fichiers dans le même répertoire, puis exécutez Install list menu.bat
en tant qu’administrateur à installer.
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
Cela enregistrera les résultats sous le format ASCII (code américain standard pour l'échange d'informations) sur votre bureau. ASCII\ANSI ne reconnaît pas tous les caractères internationaux ou étendus:
tree /f > ascii.txt
Ceci convertira votre texte ASCII en Unicode (/ c doit précéder la commande réelle):
cmd /u /c type ascii.txt > unicode.txt
Alors, pourquoi ne pas simplement considérer le fichier ascii comme un fichier temporaire et le supprimer?
del ascii.txt
Si vous devez tout mettre en ligne, vous pouvez utiliser:
tree /f > ascii.txt & cmd.exe /u /c type ascii.txt > unicode.txt & del ascii.txt
J'ai décidé de consulter tree.com
et de comprendre pourquoi il ne respecte pas le paramètre Unicode de la console. Il s'avère que (comme beaucoup d'utilitaires de fichier de ligne de commande), il utilise une bibliothèque appelée ulib.dll
pour effectuer toutes les impressions (plus précisément, TREE::DisplayName
appelle WriteString
dans ulib
).
Désormais, dans ulib
, la méthode WriteString
est implémentée dans deux classes, SCREEN
et STREAM
. La version SCREEN
utilise directement WriteConsoleW
, de sorte que tous les caractères Unicode sont correctement affichés. La version STREAM
convertit le texte Unicode en un des trois codages différents (_UseConsoleConversions
⇒ page de code de la console (GetConsoleCP
), _UseAnsiConversions
⇒ page de code ANSI par défaut, sinon ⇒ page de code OEM par défaut), puis l’écrit. Je ne sais pas comment changer le mode de conversion et je ne crois pas que la conversion puisse être désactivée.
Je n’ai que brièvement regardé cela, alors peut-être que des âmes plus aventureuses pourront en parler davantage! :-)
La réponse courte est vous ne pouvez pas et ceci est dû au fait que tree.com
est une application ANSI, même sous Windows 7.
La seule solution consiste à écrire votre propre implémentation tree
. Vous pouvez également signaler un bogue à Microsoft, mais je doute qu'ils ne soient pas déjà au courant.
Tu peux essayer
tree /A > output.txt
Bien que cela semble différent de la ligne CMD, cela pourrait quand même être acceptable. : P
Cela a fonctionné pour moi:
tree /f /a > %temp%\Listing >> files.txt
La réponse de XP1 est excellente, mais avec un inconvénient mineur: le codage de sortie est UCS2-LE, alors que je préférerais UTF8 (taille de fichier plus petite et plus répandue).
Après beaucoup de recherche et de grattage, je peux enfin vous présenter la commande suivante, qui produit un fichier UTF8-BOM:
PowerShell -Command "TREE /F | Out-File output.txt -Encoding utf8"
Si le nom du fichier de sortie contient des espaces:
PowerShell -Command "TREE /F | Out-File ""output file.txt"" -Encoding utf8"
Un grand merci à cet article: https://www.kongsli.net/2012/04/20/20/powershell-gotchas-redirect-to-file-encodes-in-unicode/
De plus, personnellement, j'ai créé les fichiers suivants dans mon 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"
Enfin, au lieu de tree > output.txt
je ne fais que xtree output.txt
J'ai réussi à obtenir le résultat tel qu'il est dans la console, avec tous les caractères non-ASCII non convertis, en envoyant le résultat sur la console (juste tree
) puis en le copiant (menu système -> Édition -> Marquer, en sélectionnant tout ). La taille de la mémoire tampon de la console doit être augmentée à l'avance, en fonction du nombre de fichiers/dossiers, dans les propriétés de la console (menu système -> Propriétés). Les autres moyens ne fonctionnaient pas. tree|clip
, mentionné dans un précédent article, convertit les caractères non ascii en caractères ascii identiques à tree>file.txt
.
J'ai réussi à sortir correctement les caractères non-ASCII de la commande tree dans un fichier via Take Command Console .
Dans le TCC, tapez "option" et sur le premier onglet, sélectionnez "Sortie Unicode". Puis lancez simplement
tree /f /a > output.txt