Вопрос: Комбинирование Batch / WMIC + ANSI / UNICODE Форматирование вывода


При создании инструмента аудита для моей сети я обнаруживаю, что WMIC выводит пробелы между символами, сопровождаемые повторением обычного текста. Например,

Эта:

@echo off
echo Foo >> "C:\test.txt"
wmic CPU Get AddressWidth >> "C:\test.txt"
wmic CPU Get Description >> "C:\test.txt"

Возвращает:

Foo 
A d d r e s s W i d t h     

 6 4                         

 D e s c r i p t i o n                                                       

 I n t e l 6 4   F a m i l y   6   M o d e l   6 9   S t e p p i n g   1     

Если я удалю (rem) echo Foo line, результат отформатирован красиво, так как существует только один тип вывода:

AddressWidth  
64            
Description                           
Intel64 Family 6 Model 69 Stepping 1  

Я читаю, что это потому, что выходы WMIC для UNICODE, а стандартные командные команды выводятся в ANSI. Можно ли объединить общий формат? Может кто-нибудь объяснить более подробно различные типы форматов, почему WMIC будет выводить на другой тип и / или любые другие факторы, способствующие этому результату? Я нашел несколько панировочные сухари, но ничего конкретного.


4
2017-09-16 12:12


Источник




Ответы:


Выполните вывод из Wmic через more:
wmic CPU Get AddressWidth |more >> "C:\test.txt"

Изменить еще один фон: проблема, которую вы видите, объясняется wmic выход - unicode utf-16. Это означает, что каждый символ (или, вернее, большинство из них) кодируется в два байта. wmic также помещает так называемую спецификацию (байтовый порядок байтов) в начале вывода. См. Ниже содержимое байта:

FF FE 44 00 65 00 73 00-63 00 72 00 69 00 70 00 ..D.e.s.c.r.i.p.

Эти первые два байта (FF FE) определяют сущность для UTF-16 и позволяют инструментам обработки данных распознавать кодирование [в виде UTF-16 little endian].
очевидно type это проверяет, и если он находит спецификацию, то правильно распознает кодировку.
С другой стороны, если вы первый  echo text а затем добавить Wmic output - вначале нет спецификации и вы можете увидеть несогласованную кодировку:
74 65 78 74 20 0D 0A 44-00 65 00 73 00 63 00 72 text ..D.e.s.c.r

Если вы его проложили type он не может вывести, как интерпретировать, / скорее всего / принимает один байт («ANSI»), и это приводит к пробелам, созданным для непечатаемых символов (нули, фактически байты верхнего порядка с двухбайтовой кодировкой символов).

more обрабатывает больше случаев (каламбур) и производит правильный вывод для основных символов ASCII, поэтому он обычно используется в качестве взлома для этой цели.

Еще одно примечание: некоторые редакторы (простой пример блокнота) будут правильно отображать кодированный файл utf-16, если он согласован - даже без спецификации. Существует способ заставить echo для вывода unicode (но остерегайтесь, чтобы он не выдавал спецификацию) - используя cmd /u вызывает выход для внутренние команды быть unicode.

Я не могу сказать, почему поддержка cmid unicode настолько ограничена (или, как говорят многие, - сломана ...) - возможно, проблемы с историей / совместимостью.

Последнее: если вам нужна лучшая поддержка юникода (среди многих других преимуществ), я бы рекомендовал перейти на powershell 


8
2017-09-16 13:14



Это похоже на принятый ответ в ссылке, которую я опубликовал, которая работает, но на самом деле не затрагивает, какова проблема или как проходит через moreрешает проблему. Я редактировал свой вопрос для ясности - root
Я расширил свой ответ (я должен признать, что я не читал связанный ответ, но more трюк является общим) - wmz
Очень тщательный и хорошо объясненный, спасибо. - root


more команда, похоже, не делает преобразования хорошо. Обратите внимание на двойной CR (\ r) в выходном файле x2.txt.

C:>wmic diskdrive where "model = 'HGST HTS725050A7E630 ATA Device'" get index >x1.txt
C:>wmic diskdrive where "model = 'HGST HTS725050A7E630 ATA Device'" get index | more >x2.txt
C:>odd x1.txt
000000    ff    fe    49    00    6e    00    64    00    65    00    78    00    20    00    20    00
       377 376   I  \0   n  \0   d  \0   e  \0   x  \0      \0      \0
000010    0d    00    0a    00    30    00    20    00    20    00    20    00    20    00    20    00
        \r  \0  \n  \0   0  \0      \0      \0      \0      \0      \0
000020    20    00    0d    00    0a    00
            \0  \r  \0  \n  \0
000026

C:>odd x2.txt
000000    49    6e    64    65    78    20    20    0d    0d    0a    30    20    20    20    20    20
         I   n   d   e   x          \r  \r  \n   0
000010    20    0d    0d    0a    0d    0d    0a    0d    0a
            \r  \r  \n  \r  \r  \n  \r  \n

Обновить Похоже, PowerShell может справиться с этим лучше.

Get-WmiObject Win32_diskdrive |
    Where-Object { $_.Model -like '*WD*' } |
    Select-Object -Property Model |
    Out-File -PSPath t1.txt

Get-WmiObject Win32_diskdrive |
    Where-Object { $_.Model -like '*WD*' } |
    Select-Object -Property Model |
    Out-File -PSPath t2.txt -Encoding default

Понятно, что CIM - это направление PowerShell в будущем. Лучше начать использовать его сейчас.

Get-CimInstance CIM_DiskDrive |
    Where-Object { $_.Model -like '*WD*' } |
    Select-Object -Property Model |
    Out-File -PSPath t1.txt

Get-CimInstance CIM_DiskDrive |
    Where-Object { $_.Model -like '*WD*' } |
    Select-Object -Property Model |
    Out-File -PSPath t2.txt -Encoding default

2
2018-05-11 14:51



Есть ли проблема в этой проблеме? - thaimin
@thaimin - Обновлен ответ с возможными решениями для проблемы преобразования кодировки. - lit