Как удалить символ NULL (0x00) из объекта в PowerShell

У меня есть файл .CSV, который я создал с помощью утилиты командной строки BCP SQL Server BULK-COPY для создания дампа нескольких таблиц базы данных.

Поскольку я хочу импортировать эти файлы .CSV с помощью Powershell и преобразовать их в хороший отчет с помощью командлета format-table, у меня возникают проблемы с выравниванием столбцов и т. д. потому что некоторые столбцы содержат NULL из SQL Server. У меня нет возможности сначала преобразовать NULL из SQL Server; из-за того, как я экспортирую таблицу в CSV.

Поэтому я хотел бы удалить все NULL из файла .CSV, прежде чем пытаться передать его в командлет таблицы форматирования.

Мой основной код ниже:

$CSV=import-csv "c:\temp\tablename.csv"
$CSV | format-table -autosize | out-string -width 4096 >"C:\TEMP\tablename.txt"

Я пытался сделать что-то вроде:

$CSV | -replace($null,"") | format-table -autosize | out-string -width 4096 > "C:\TEMP\tablename.txt"

но я все еще получаю NULL.

Кто-нибудь знает, как удалить NULL из моего CSV, чтобы я мог отобразить хороший табличный отчет. Я хочу, чтобы эти отчеты .TXT импортировались в SVN, но значения NULL вызовут у меня проблемы, к тому же это искажает отчеты.

CSV-файл, как показано в шестнадцатеричном редакторе:

00000EA0h: 31 38 39 2C 31 31 39 2C 37 35 29 2C 77 68 69 74 189,119,75),whit  
00000EB0h: 65 2C 77 68 69 74 65 2C 2C 2C 2C 2C 2C 2C 2C 2C e,white,,,,,,,,,  
00000EC0h: 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C ,,,,,,,,,,,,,,,,  
00000ED0h: 2C 2C 0D 0A 61 63 62 34 33 5F 30 31 2C 4F 4E 2C ,,..acb43_01,ON,  
00000EE0h: 00 2C 32 37 2C 39 39 2C 2F 61 63 62 34 33 5F 30 .,27,99,/acb43_0  
00000EF0h: 31 2F 34 33 62 61 6C 61 6E 63 65 73 2E 67 69 66 1/43balances.gif  

Обратите внимание, что в EE0h первый символ равен NULL, 0x00.


person user500741    schedule 25.03.2012    source источник
comment
Значение NULL в вашем заголовке в сочетании с тегом sql-server вводило в заблуждение, поэтому я немного изменил заголовок, чтобы устранить двусмысленность. Я не уверен, что сейчас это звучит неуклюже или неловко, поэтому, пожалуйста, не стесняйтесь редактировать его снова по своему усмотрению.   -  person Andriy M    schedule 26.03.2012


Ответы (6)


Немного поиграв, я наконец понял, что этот синтаксис работает:

(Get-Content "C:\temp\tablename.csv") -replace "`0", "" | Set-Content "C:\temp\tablename.csv"
person user500741    schedule 26.03.2012
comment
Если бы я мог сердце пост, я бы. Я использовал сценарий PowerShell для изменения XML-файла манифеста Android в целях управления версиями, и эта ошибка HEX 0x00 очень разочаровывала. Спасибо! - person srbrills; 05.10.2017

Все представленные ответы являются обходными и не решают основную проблему, заключающуюся в том, что powershell по умолчанию использует кодировку utf-16 (вот почему вы получаете NULL, т.е. 0x00 между всеми символами). Решение состоит в том, чтобы указать powershell использовать utf-8:

$stuff | Out-File $out_path -Encoding UTF8

Также см. эту тему

person user2426679    schedule 04.05.2016
comment
Я согласен с @user2426679. Этот ответ следует принять. Я использовал string.Replace, а затем сохранял с помощью Out-File. Проблема заключалась в том, что кодировка и указание UTF8 работали как шарм. - person Mayur Dhingra; 17.02.2017
comment
Спасибо ! У меня была аналогичная проблема с синтаксическим анализатором npm. Несмотря на то, что автоматически сгенерированный xml был установлен на ‹?xml version=1.0 encoding=UTF-8?› во время создания, выполнение вышеуказанного исправило небелые символы в моем шестигранный вид. И уж точно лучший способ, чем замена отдельных символов. - person Vinay; 16.05.2018

Обновление. Теперь, когда я понимаю, что вы подразумеваете под NULL (hex 0x00), я могу предложить вам другой подход.

Вы можете просто отфильтровать эти байты, прочитав файл как двоичный файл следующим образом:

Get-Content "c:\temp\tablename.csv" -Encoding Byte | ? {$_ -ne 0x00} | Set-Content "c:\temp\tablename2.csv" -Encoding Byte
person Andy Arismendi    schedule 25.03.2012
comment
Привет - спасибо за быстрый ответ. То, что вы сказали, имеет смысл; однако я попробовал оба ваших метода, и результирующий вывод по-прежнему содержит 0x00 NULL. Вот фрагмент вывода. Обратите внимание на строку EE0h, первый символ 00. ` 00000EC0h: 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C 2C ,,,,,,,,,,,,,,, 00000ED0h: 2C 2C 0D 0A 61 63 62 34 33 5F 30 31 2C 4F 4E 2C ,,..acb43_01,ON, 00000EE0h: 00 2C 32 37 2C 39 39 2C 2F 61 63 62 34 33 5F 30 .,27,930,/acb:0EF00EF00EF00EF0EF 31 2F 34 33 62 61 6C 61 6E 63 65 73 2E 67 69 66 1/43balances.gif` - person user500741; 26.03.2012
comment
-- Извините, я попытался отредактировать исходный вопрос и не могу заставить форматирование оставаться в режиме блокировки. - person user500741; 26.03.2012
comment
@ user500741 Не забывайте, это просто текст, поэтому любой буквальный текст, который вы хотите удалить, будет тем, что вы будете использовать в качестве первого аргумента оператора -replace. Я немного изменил свои примеры, чтобы вам было легче это увидеть. - person Andy Arismendi; 26.03.2012
comment
Спасибо за ответ - абсолютное значение, если смотреть на него в непечатном виде. Попытка это было 00 тоже не работает. Шестнадцатеричный дамп, который я предоставил, показывает его как 0x00, а сторона ASCII просто показывает его как непечатаемый символ с использованием .. - person user500741; 26.03.2012

Используйте '\xnn' для сопоставления символов по их шестнадцатеричному представлению:

(get-content c:\temp\tablename.csv) -replace '\x00','' | set-content c:\temp\tablename.csv
person mjolinor    schedule 26.03.2012

-replace "`0", " "

Это сработало для меня в текстовом файле просто отлично.

person psstarkey    schedule 08.08.2012

Исходя из ответа Энди и вашего ответа, похоже, что «нулевое» значение, от которого вы хотите избавиться, на самом деле «00» в тексте.

Итак, вы хотели бы сделать это вместо этого:

(Get-Content "C:\temp\tablename.csv") -replace " 00 ", " " | Set-Content "C:\temp\tablename.csv"

Это преобразует:

00000EE0h: 00 2C 32

в:

00000EE0h: 2C 32

person Huon Imberger    schedule 26.03.2012
comment
Нет, это был шестнадцатеричный дамп файла, чтобы показать, как выглядит каждый байт. NotePad++, например, показывает NULL. Если я посмотрю на него в шестнадцатеричном виде, он будет отображаться как байт 0x00 или . так как это не для печати. - person user500741; 26.03.2012