سؤال

أحاول استخدام أمر الشجرة في سطر أوامر Windows لإنشاء ملف نصي يسرد محتويات الدليل، ولكن عندما أقوم بتوجيه الإخراج، تصبح أحرف Unicode محشوة.

إليك الأمر الذي أستخدمه:

tree /f /a > output.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ö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

لكن الملف النصي ليس جيدًا:

\---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

كيف يمكنني اصلاح هذا؟من الناحية المثالية، سيكون الملف النصي مطابقًا تمامًا للإخراج الموجود في نافذة وحدة التحكم.

لقد جربت اقتراح Chris Jester-Young (ماذا حدث، هل قمت بحذفه يا كريس؟) لتشغيل سطر الأوامر باستخدام المفتاح /U، بدا الأمر تمامًا كما أحتاجه ولكن لا يبدو أنه يعمل.لقد حاولت فتح الملف في كل من VS2008 والمفكرة وكلاهما يظهر نفس الأحرف غير الصحيحة.

هل كانت مفيدة؟

المحلول

هل جرب شخص ما هذا بالفعل:

tree /f /a |clip

هل تريد فتح المفكرة باستخدام ctrl + V وحفظها في المفكرة بصيغة input.txt مع دعم Unicode؟

نصائح أخرى

إذا قمت بالإخراج بتنسيق غير Unicode (وهو ما تفعله على ما يبدو)، فيجب عليك عرض الملف النصي الذي قمت بإنشائه باستخدام نفس التشفير الذي تستخدمه نافذة وحدة التحكم.لهذا السبب يبدو صحيحًا في وحدة التحكم.في بعض برامج تحرير النصوص، يمكنك اختيار ترميز (أو "صفحة رموز") عند فتح ملف.(كيفية الإخراج كـ Unicode لا أعرف.cmd /U لا يفعل ما تقوله الوثائق.)

يعتمد ترميز وحدة التحكم على تثبيت Windows لديك.بالنسبة لي، إنه "أوروبا الغربية (DOS)" (أو فقط "MS-DOS") في Microsoft Word.

استخدم بوويرشيل:

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"

منه إجابة, ، كتب @Chris Jester-Young:

في هذه اللحظة ulib, ، ال WriteString يتم تنفيذ الطريقة في فئتين ، SCREEN و STREAM.ال SCREEN يستخدم الإصدار WriteConsoleW مباشرة ، لذلك يتم عرض جميع أحرف Unicode بشكل صحيح.ال STREAM يحول الإصدار نص Unicode إلى واحد من ثلاثة ترميزات مختلفة (_UseConsoleConversions codepage وحدة التحكم (GetConsoleCP), _UseAnsiConversions ⇒ الافتراضي ANSI Codepage ، وإلا

هذا يعني أنه لا يمكننا الاعتماد على الحصول على الأحرف من الدفق.لن تعمل عمليات إعادة توجيه الملفات.علينا أن نعتمد على الكتابة إلى وحدة التحكم للحصول على أحرف Unicode.

الحل البديل، أو الاختراق، هو كتابة الشجرة على وحدة التحكم ثم تفريغ المخزن المؤقت في ملف.

لقد قمت بكتابة البرامج النصية لإضافة قائمة سياق الشجرة عند النقر بزر الماوس الأيمن على الدلائل في Explorer.احفظ الملفات في نفس الدليل ثم قم بتشغيلها 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

قررت أنني يجب أن ألقي نظرة tree.com واكتشف سبب عدم احترام إعداد Unicode لوحدة التحكم.اتضح أنه (مثل العديد من الأدوات المساعدة لملفات سطر الأوامر)، يستخدم مكتبة تسمى ulib.dll للقيام بجميع عمليات الطباعة (على وجه التحديد، TREE::DisplayName المكالمات WriteString في ulib).

في هذه اللحظة ulib, ، ال WriteString يتم تنفيذ الطريقة في فئتين، SCREEN و STREAM.ال SCREEN يستخدم الإصدار WriteConsoleW مباشرةً، بحيث يتم عرض كافة أحرف Unicode بشكل صحيح.ال STREAM يقوم الإصدار بتحويل نص Unicode إلى واحد من ثلاثة ترميزات مختلفة (_UseConsoleConversions ⇒ صفحة الرموز لوحدة التحكم (GetConsoleCP), _UseAnsiConversions ⇒ صفحة رموز ANSI الافتراضية، وإلا ⇒ صفحة رموز OEM الافتراضية)، ثم يكتب ذلك.لا أعرف كيفية تغيير وضع التحويل، ولا أعتقد أنه يمكن تعطيل التحويل.

لقد ألقيت نظرة سريعة على هذا فقط، لذلك ربما يمكن للأرواح الأكثر ميلاً إلى المغامرة التحدث أكثر عنه!:-)

سيؤدي هذا إلى حفظ النتائج بتنسيق ASCII (الرمز القياسي الأمريكي لتبادل المعلومات) على سطح المكتب لديك، ولا يتعرف ASCII\ANSI على كل حرف دولي أو موسع:

tree /f > ascii.txt

سيؤدي هذا إلى تحويل نص ASCII إلى Unicode (يجب أن يسبق /c الأمر الفعلي):

cmd /u /c type ascii.txt > unicode.txt

فلماذا لا تفكر في ملف ascii كملف مؤقت وتحذفه؟

del ascii.txt

إذا كان يجب عليك وضع الكل في سطر واحد، فيمكنك استخدام:

tree /f > ascii.txt & cmd.exe /u /c type ascii.txt > unicode.txt & del ascii.txt

الجواب القصير هو انت لا تستطيع وهذا بسبب tree.com هو تطبيق ANSI، حتى على نظام التشغيل Windows 7.

الحل الوحيد هو أن تكتب بنفسك tree تطبيق.يمكنك أيضًا الإبلاغ عن خطأ إلى Microsoft، لكني أشك في أنهم ليسوا على علم به بالفعل.

يمكنك المحاولة

tree /A > output.txt

على الرغم من أنه يبدو مختلفًا عن خط CMD، إلا أنه لا يزال مقبولاً.:ص

لقد نجح هذا بالنسبة لي:

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

لقد نجحت في الحصول على الإخراج كما هو في وحدة التحكم، مع عدم تحويل كافة الأحرف غير ascii، عن طريق الإخراج إلى وحدة التحكم (فقط tree) ثم النسخ منه (قائمة النظام -> تحرير -> تحديد، تحديد الكل، أدخل).يجب زيادة حجم المخزن المؤقت لوحدة التحكم مسبقًا، اعتمادًا على عدد الملفات/المجلدات، في خصائص وحدة التحكم (قائمة النظام -> الخصائص).طرق أخرى لم تنجح. tree|clip, ، المذكور في منشور سابق، يحول الأحرف غير ascii إلى أحرف ascii نفسها tree>file.txt.

لقد تمكنت من إخراج أحرف غير ascii بشكل صحيح من أمر الشجرة إلى ملف عبر خذ وحدة التحكم في الأوامر.

في TCC، اكتب "الخيار" وفي علامة التبويب الأولى حدد "إخراج Unicode".ثم قم بالتشغيل ببساطة

tree /f /a > output.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 المحمولة وقد عملت بشكل جيد.

من داخل الدوس ....

C:\doskey [أدخل] {لتمكين اختصارات لوحة المفاتيح المفيدة}

C: ree j:\ >> d:\MyCatalog.txt /a [أدخل] {j:= هو محرك أقراص USB الخاص بي؛d:= هو المكان الذي أريد الكتالوج فيه؛/a = شاهد المنشورات الأخرى على هذه الصفحة}

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top