В данной статье приведу несколько практических примеров по изменению кодировки в PowerShell. Ранее я уже публиковал статью про смену кодировки, когда не отображались кириллические символы, сейчас рассмотрю тему более подробно.
Смена кодировки вывода в консоль
Сменить кодировку вывода в консоль можно одним из предложенных ниже способов:
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("utf-8")
В данных примерах меняем ее на utf8. Это решает проблему с отображением кириллицы.
Кракозябры в PowerShell ISE можно побороть вот так (сменив кодировку на cp866):
[Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866')
При сборке скрипта в exe файл через Win-PS2EXE тоже были проблемы с кодировкой при выводе кириллицы:
В Windows 10 помогло это:
[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("windows-1251")
В Win7 нужную кодировку не подобрал.
Смена кодировки вывода в файл Out-File
Вывод результата консольной утилиты, запущенной через PowerShell, в txt файл выдавал кракозябры. Помогло использование параметра -Encoding и выбор кодировки oem в конвейере в качестве параметра командлета Out-File (в примере zab_api.exe это консольная утилита, вывод которой нужно было писать в файл).
.zab_api.exe | Out-File data.txt -Encoding oem
When I try to read a file with Russian encoding
(Example):
$CommentChar = @(";")
$commentRegex = "^s*([$($CommentChar -join '')].*)$"
switch -regex -file .myinifile.ini {
$commentRegex {
$value = $matches[1]
Write-host "$value"
}
}
Instead of Russian characters, I get that:
�������� ����, 0 — ���������
How can I change the encoding to Windows 1251 ?
asked Dec 14, 2021 at 7:55
6
You can read a file with encoding codepage 1251 like below:
# for .Net methods, you need absolute paths
$file = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($pwd, '.myinifile.ini'))
# get the 1251 encoding object
$cyrillicEnc = [System.Text.Encoding]::GetEncoding("windows-1251")
# read all lines in an array
$contents = [System.IO.File]::ReadAllLines($file, $cyrillicEnc)
# and loop over them using your regex
$CommentChar = ";"
$commentRegex = "^s*([$($CommentChar -join '')].*)$"
foreach ($line in $contents) {
if ($line -match $commentRegex) { Write-Host $matches[1] }
}
Assuming your file looks anything like this:
Доброе утро
; Рад познакомиться с тобой
Как дела?
The result of the above code would be
; Рад познакомиться с тобой
answered Dec 14, 2021 at 13:09
TheoTheo
55.4k8 gold badges23 silver badges40 bronze badges
Posted on 18/05/2016 by sie
Традиционные приложения (native application) запускаемые в консоли cmd.exe, как правило не являются unicode-приложениями. Иначе говоря, они ожидают ввод и выводят информацию в обычной кодировке, например, CP866 или CP1251. С другой стороны, Powershell является unicode-приложением. Это означает, что Powershell должен выполнять перекодировку в обе стороны при вызове native application. По умолчанию он это делает в большинстве случаев правильно. Но если на целевой системе вместо кодировки по умолчанию для non-unicode программ стоит не «Русский», что соответствует CP866, а «Английский» — CP437, при работе «русской» native application мы получим проблемы: программа не будет понимать ввод, а ее вывод будет абракадаброй.
Ситуацию можно исправить. В Powershell за перекодировку отвечают две переменные:
[Console]::OutputEncoding : отвечает за перекодировку <native application> -> <Powershell>
$OutputEncoding : отвечает за перекодировку <Powershell> -> <native application>
(Есть ещё [Console]::InputEncoding, которая отвечает за ввод с клавиатуры в консольное приложение)
Есть ещё случай, когда вывод native application происходит не в консоль, а перехватывается Powershell (например, при удаленном вызове через WS-Management). Тогда полученные строки придётся перекодировать «вручную». Пример такого скрипта https://xaegr.wordpress.com/2007/01/24/decoder/
Спасибо за наводку Александр AKA Kazun
Примеры:
[Console]::OutputEncoding = [Text.Encoding]::Unicode
[Console]::OutputEncoding = [Text.Encoding]::UTF8
$OutputEncoding = [Text.Encoding]::GetEncoding(1251)
[Text.Encoding]::Unicode
Filed under: Powershell, Windows |
- Remove From My Forums
-
Вопрос
-
Добрый день!
Есть необходимость ввести в какую-либо переменную PowerShell вывод команды
Но он сохраняется в неверном формате:
PS C:Documents and Settingslushnikov> ipconfig /all Настройка протокола IP для Windows Имя компьютера . . . . . . . . . : computername Основной DNS-суффикс . . . . . . : mydomain.ru Тип узла. . . . . . . . . . . . . : гибридный IP-маршрутизация включена . . . . : нет WINS-прокси включен . . . . . . . : нет Порядок просмотра суффиксов DNS . : Mydomain.ru mydomain.ru Подключение по локальной сети — Ethernet адаптер: Состояние сети . . . . . . . . . : сеть отключена Описание . . . . . . . . . . . . : Intel(R) PRO/100 VE Network Connection Физический адрес. . . . . . . . . : MAC Беспроводное сетевое соединение — Ethernet адаптер: DNS-суффикс этого подключения . . : mydomain.ru Описание . . . . . . . . . . . . : Intel(R) PRO/Wireless 3945ABG Network Connection Физический адрес. . . . . . . . . : MAC Dhcp включен. . . . . . . . . . . : да Автонастройка включена . . . . . : да IP-адрес . . . . . . . . . . . . : 172.16.7.222 Маска подсети . . . . . . . . . . : 255.255.255.0 Основной шлюз . . . . . . . . . . : 172.16.7.1 DHCP-сервер . . . . . . . . . . . : 172.16.7.15 DNS-серверы . . . . . . . . . . . : 172.16.7.4 172.16.7.3 Основной WINS-сервер . . . . . . : 172.16.7.4 Аренда получена . . . . . . . . . : 3 февраля 2009 г. 10:44:35 Аренда истекает . . . . . . . . . : 4 февраля 2009 г. 11:44:35 PS C:Documents and Settingslushnikov> $IpconfigText = ipconfig /all | Out-String PS C:Documents and Settingslushnikov> $IpconfigText ═рёЄЁющър яЁюЄюъюыр IP фы Windows ╚ь ъюья№■ЄхЁр . . . . . . . . . : computername ╬ёэютэющ DNS-ёєЇЇшъё . . . . . . : Mydomain.ru ╥шя єчыр. . . . . . . . . . . . . : ушсЁшфэ√щ IP-ьрЁ°ЁєЄшчрЎш тъы■ўхэр . . . . : эхЄ WINS-яЁюъёш тъы■ўхэ . . . . . . . : эхЄ ╧юЁ фюъ яЁюёьюЄЁр ёєЇЇшъёют DNS . : Mydomain.ru mydomain.ru ╧юфъы■ўхэшх яю ыюъры№эющ ёхЄш — Ethernet рфряЄхЁ: ╤юёЄю эшх ёхЄш . . . . . . . . . : ёхЄ№ юЄъы■ўхэр ╬яшёрэшх . . . . . . . . . . . . : Intel(R) PRO/100 VE Network Connection ╘шчшўхёъшщ рфЁхё. . . . . . . . . : MAC ┴хёяЁютюфэюх ёхЄхтюх ёюхфшэхэшх — Ethernet рфряЄхЁ: DNS-ёєЇЇшъё ¤Єюую яюфъы■ўхэш . . : mydomain.ru ╬яшёрэшх . . . . . . . . . . . . : Intel(R) PRO/Wireless 3945ABG Network Connection ╘шчшўхёъшщ рфЁхё. . . . . . . . . : MAC Dhcp тъы■ўхэ. . . . . . . . . . . : фр └тЄюэрёЄЁющър тъы■ўхэр . . . . . : фр IP-рфЁхё . . . . . . . . . . . . : 172.16.7.222 ╠рёър яюфёхЄш . . . . . . . . . . : 255.255.255.0 ╬ёэютэющ °ы■ч . . . . . . . . . . : 172.16.7.1 DHCP-ёхЁтхЁ . . . . . . . . . . . : 172.16.7.15 DNS-ёхЁтхЁ√ . . . . . . . . . . . : 172.16.7.4 172.16.7.3 ╬ёэютэющ WINS-ёхЁтхЁ . . . . . . : 172.16.7.4 └Ёхэфр яюыєўхэр . . . . . . . . . : 3 ЇхтЁры 2009 у. 10:44:35 └Ёхэфр шёЄхърхЄ . . . . . . . . . : 4 ЇхтЁры 2009 у. 11:44:35 ОС — Windows XP SP3 RUS
Под Windows Vista SP1 RUS все ок, но надо сделать именно под XPВот эту статью читал, но не могу подобрать кодировку, из какой в какую надо переводить…
Прошу помощи в декодировании вывода команды ipconfig /all
Ответы
-
function ConvertTo-Encoding ([string]$From, [string]$To){ Begin{ $encFrom = [System.Text.Encoding]::GetEncoding($from) $encTo = [System.Text.Encoding]::GetEncoding($to) } Process{ $bytes = $encTo.GetBytes($_) $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes) $encTo.GetString($bytes) } } $ipconfigData | ConvertTo-Encoding windows-1251 cp866
AKA Xaegr, MCSE: Security, Messaging; MCITP: ServerEnterprise Administrator; Блог: http://xaegr.wordpress.com
-
Помечено в качестве ответа
4 февраля 2009 г. 12:47
-
Помечено в качестве ответа
- Remove From My Forums
-
Вопрос
-
Получаю по API JSON результат. Но русские буквы отображаются в виде знаков вопроса. Есть идеи, товарищи? Спасибо заранее
Что запускаю:
$url2 = "http://********/rooms?limit=3&access_token=******" $rres = Invoke-WebRequest -Method GET -Uri $url2 -ContentType "application/json;charset=utf-8" | ConvertFrom-Json $Lmres = $rres.chunk Write-Host $Lmres[0].Content
Получаю:
@{body=???? ??????) ; msgtype=m.text} @{body=??????????????; msgtype=m.text} @{body=??????????; msgtype=m.text}
Кодировку запроса к json менял на win-1251, ничего не изменилось.
Ответы
-
С проблемными сайтами отдает ISO-8859-1(что является багом), функцию конвертирования, я привел выше.
PS > $res = iwr http://php.su PS > $res.BaseResponse IsMutuallyAuthenticated : False Cookies : {} Headers : {Transfer-Encoding, Connection, Vary, Content-Type...} SupportsHeaders : True ContentLength : -1 ContentEncoding : ContentType : text/html CharacterSet : ISO-8859-1 Server : nginx LastModified : 2/28/2018 1:12:32 PM StatusCode : OK StatusDescription : OK ProtocolVersion : 1.1 ResponseUri : http://www.php.su/ Method : GET IsFromCache : False PS > $res.BaseResponse.CharacterSet ISO-8859-1
PS. Можно скачать портативную версию PowerShell Core и написать скрипт в ней — https://github.com/PowerShell/PowerShell/releases/download/v6.0.1/PowerShell-6.0.1-win-x64.zip
-
Помечено в качестве ответа
1 марта 2018 г. 6:36
-
Помечено в качестве ответа
-
Данного поля в заголовке может и не быть. С WebClient нормально отображается кодировка?
$wb = New-object System.Net.WebClient -Property @{Encoding = [System.Text.Encoding]::UTF8} $wb.Headers.Add("Content-Type","application/json;charset=utf-8") $wb.DownloadString($url2)
-
Помечено в качестве ответа
[technoir]
1 марта 2018 г. 6:36
-
Помечено в качестве ответа
Вопрос:
Я не могу заменить успешно кириллицу.
Мой файл кодируется UTF-8 с помощью спецификации /
Код сценария powershell:
$Title = "название видео"
$Title = $Title.Replace("название", "")
Write-Host $Title
cmd /c pause
Результат:
Лучший ответ:
Решение:
function ConvertTo-Encoding ([string]$From, [string]$To){
Begin{
$encFrom = [System.Text.Encoding]::GetEncoding($from)
$encTo = [System.Text.Encoding]::GetEncoding($to)
}
Process{
$bytes = $encTo.GetBytes($_)
$bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes)
$encTo.GetString($bytes)
}
}
[System.Text.Encoding]::Default.Codepage
$Title = "название видео" | ConvertTo-Encoding "UTF-8" "windows-1251"
Write-Host $Title
$Title = $Title.Replace(("название" | ConvertTo-Encoding "UTF-8" "windows-1251"), "")
Write-Host $Title
cmd /c pause
Ответ №1
Я не могу воспроизвести вашу проблему. Тем не менее, позвольте мне предположить, что вывод из [System.Console]::OutputEncoding.Codepage
– 1251
. Вы можете изменить кодировку консоли на Unicode (UTF-8)
(кодовая страница 65001
) на лету; попробуйте изменить свой сценарий следующим образом:
### debug ### [System.Console]::OutputEncoding
[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8
### debug ### [System.Console]::OutputEncoding
$Title = "название видео"
$Title = $Title.Replace("название", "")
Write-Host $Title
pause
Или измените консольную кодировку на Unicode
(кодовая страница 1200
), используя
[System.Console]::OutputEncoding = [System.Text.Encoding]::Unicode
Ответ №2
Измените шрифт из растра на некоторые шрифты истинного шрифта
I need to convert a text file to UTF-8 format via Windows command prompt. This needs to be done on another machine and I do not have rights to install software on that machine. I need something like:
c:notepad source-file target-file --encoding option
Is there a Windows command prompt utility which can do it?
asked Jan 5, 2017 at 13:58
I need to convert a text file to utf-8 format via windows command prompt
You can easily do this with PowerShell:
Get-Content .test.txt | Set-Content -Encoding utf8 test-utf8.txt
Further Reading
- Convert from most encodings to utf8 with powershell
answered Jan 5, 2017 at 14:38
DavidPostill♦DavidPostill
149k77 gold badges344 silver badges383 bronze badges
13
Use iconv
from GNUWin32 pack. It is much faster, especially if your files are about or more than 1 Gb.
"C:Program Files (x86)GnuWin32biniconv.exe" -f cp1251 -t utf-8 source.txt > result.txt
answered Feb 21, 2018 at 15:09
Raul N-kRaul N-k
511 silver badge1 bronze badge
3
Here is for each convert *.text file to *.sql file:
foreach ($file in get-ChildItem *.txt) {
Echo $file.name
Get-Content $file | Set-Content -Encoding utf8 ("$file.name" +".sql")
}
answered May 20, 2019 at 10:20
1
You can do this from the command prompt as follows:
powershell -command "Get-Content .test.txt" > test-utf8.txt
It turns out that piping the output to a file from the command prompt saves as utf-8.
answered Sep 30, 2020 at 20:49
1
POWERSHELL: # Assumes Windows PowerShell, use -Encoding utf8BOM with PowerShell Core. For multiple files:
FIRST SOLUTION:
$files = Get-ChildItem c:Folder1 -Filter *.txt
foreach ($file in $files) {
Get-Content $file.FullName | Set-Content "E:TempDestination$($file.Name)" -Encoding utf8BOM
}
OR, SECOND SOLUTION (for multiple files):
get-item C:Folder1*.* | foreach-object {get-content -Encoding utf8BOM $_ | out-file ("C:Folder1" + $_.Name) -encoding default}
OR, THE THIRD SOLUTION: (only for 2 files)
$a = "C:/Folder1/TEST_ro.txt"
$b = "C:/Folder1/TEST_ro-2.txt"
(Get-Content -path $a) | Set-Content -Encoding UTF8BOM -Path $b
answered Aug 1, 2022 at 14:19
Just MeJust Me
7568 silver badges33 bronze badges
Простенькая функция для перекодировки текста из одной кодировки в другую.
function ConvertTo-Encoding ([string]$From, [string]$To){ Begin{ $encFrom = [System.Text.Encoding]::GetEncoding($from) $encTo = [System.Text.Encoding]::GetEncoding($to) } Process{ $bytes = $encTo.GetBytes($_) $bytes = [System.Text.Encoding]::Convert($encFrom, $encTo, $bytes) $encTo.GetString($bytes) } }
И на пару — для получения списка доступных кодировок:
function Get-Encodings {[System.Text.Encoding]::GetEncodings()}
Можно конечно и [s[tab].t[tab].encodi[tab]::[tab][tab] набрать, но мне показалось что в виде классической Get- функции это будет красивее 🙂 (Если у вас вдруг еще не дополнется .Net по табу — см. сюда)
Функция берет строку или массив строк на вход, и в качестве параметров указываются названия исходной и нужной кодировок (см. Get-Encodings).
Например:
PS D:PowerShell> "Проверка" | ConvertTo-Encoding windows-1251 koi8-r рТПЧЕТЛБ PS D:PowerShell> "рТПЧЕТЛБ" | ConvertTo-Encoding koi8-r windows-1251 Проверка
Ну или берём строки из файла и переправляем в другой файл:
PS D:PowerShell> Get-Content notes.txt | ConvertTo-Encoding "windows-1251" "koi8-r" | Set-Content decoded.txt
То же самое но другими буквами 😉
PS D:PowerShell> cat notes.txt | ConvertTo-Encoding "windows-1251" "koi8-r" > decoded.txt
Хотел приделать возможность указывать строку для перекодировки в качестве параметра (без «|»), но к сожалению такой финт ушами (несколько Parameter Set) можно сделать только в коммандлетах… В функциях — либо одно, либо другое 😦
Впрочем потом может напишу командлет где можно будет делать и так и эдак.