использование powershell для замены расширенного символа ascii в текстовом файле - PullRequest
0 голосов
/ 05 сентября 2018

Мне нужно заменить шестнадцатеричный символ 93 на строку "" в нескольких файлах csv. Ниже приведен код, который я использую. Но это не работает, я думаю, что причина этого не в том, что шестнадцатеричное значение больше 7F (дек. 127). Я пробовал несколько других методов безрезультатно. Любая помощь будет оценена.

$q1 = [String](0x93 -as [char])
Get-ChildItem ".\*.csv" -Recurse | ForEach {
(Get-Content $_ | ForEach  { $_.replace($q1, '""') }) |
     Set-Content $_
}

Примечание: Attach - изображение дамп формата-hex моего тестового файла. Первый символ - тот, который мне нужен для замены: enter image description here

1 Ответ

0 голосов
/ 05 сентября 2018

В Windows PowerShell кодировка символов по умолчанию при чтении из / записи в файлах - это «ANSI» , то есть устаревшая 8-битная кодовая страница, подразумеваемая языком активной системы .
(Напротив, PowerShell Core по умолчанию использует UTF-8.)

Например, кодовая страница, связанная с системным языком в системе на английском и американском языках, равна 1252, т. Е. Windows-1252 , где кодовая точка 0x93 является не-ASCII кавычка.

Но как только содержимое текстового файла будет считано в память, в памяти символы строки представляются в виде UTF-16LE кодовых единиц , т. Е. как .NET [string] экземпляры.

Как символ Unicode , имеет кодовую точку U+201c, выраженную как 0x201c в UTF-16LE.

Следовательно - поскольку в памяти все строки являются кодовыми единицами UTF-16LE, необходимо заменить на [char] 0x201c:

$q1 = [char] 0x201c  # “
Get-ChildItem *.csv -Recurse | ForEach-Object {
  (Get-Content $_.FullName) -replace $q1, '""' | Set-Content $_.FullName
}

Обратите внимание, что Set-Content также использует кодировку символов по умолчанию, поэтому переписанные файлы также будут использовать кодировку "ANSI" - используйте параметр -Encoding для изменения выходной кодировки, если это необходимо.

Также обратите внимание на (...) вокруг вызова Get-Content, который гарантирует, что входной файл, который я прочитал в память полностью вперед, что позволяет записывать обратно в тот же файл в том же конвейере.
Хотя этот подход удобен, имейте в виду, что он несет небольшой риск потери данных, если запись во входной файл прерывается до завершения.


Преобразование кодовой точки ANSI в кодовую точку Unicode

Ниже показано, как можно преобразовать 8-битную кодовую точку ANSI, такую ​​как 0x93, в эквивалентную кодовую точку UTF-16, 0x201c:

# Convert an array of "ANSI" code points (1 byte each) to the UTF-16
# string they represent. 
# Note: In Windows PowerShell, [Text.Encoding]::Default contains
#       the "ANSI" encoding set by the system locale.
$str = [Text.Encoding]::Default.GetString([byte[]] 0x93) # -> '“'

# Get the UTF-16 code points of the characters making up the string.
$codePoints = [int[]] [char[]] $str

# Format the first and only code point as a hex. number.
'0x{0:x}' -f $codePoints[0]  # -> '0x201c'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...