Удалите запятые из чисел в CSV
У меня есть информация о папках для всех пользовательских папок. Он выгружается в файл CSV следующим образом:
Servername, F:\Users\user, 9,355.7602 MB, 264, 3054, 03/15/2000 13:28:48, 12/10/2018 11:58:29
Мы не можем работать с данными из-за разделителя тысяч в 3-м столбце. Я мог бы запустить сценарии отчета еще раз, но у нас много файловых серверов и большое количество пользователей, в частности, на одном, поэтому повторный запуск занимает очень много времени. Причина наличия запятых в том, что данные были записаны в виде строки, а не числа.
Я могу импортировать и конвертировать, единственная проблема в том, что любое число больше 1000 будет неправильным, и тогда все остальные данные будут отключены на 1 столбец. Я хотел бы заменить любую запятую между двумя числами. Не похоже, что это так сложно сделать с PowerShell, но мне не удалось ничего найти.
2 ответа
Если вы предполагаете, что столбцы данных разделены запятыми и пробелами и в ваших числах нет пробелов, вы можете использовать-replace
оператор для этого.
$line = 'Servername, F:\Users\user, 9,355.7602 MB, 264, 3054, 03/15/2000 13:28:48, 12/10/2018 11:58:29'
$line -replace '(?<=\d),(?=\d)'
Если вы читаете данные из файла, вы можете прочитать данные с помощью Get-Content, заменить свои данные и обновить файл с помощью Set-Content.
(Get-Content file.csv) -replace '(?<=\d),(?=\d)' | Set-Content file.csv
Если файл большой, вы можете использовать более быстрый оператор переключения.
$data = switch -regex -file file.csv {
'(?<=\d),(?=\d)' { $_ -replace '(?<=\d),(?=\d)' }
default {$_}
}
$data | Set-Content file.csv
Пояснение:
(?<=\d)
использует утверждение положительного просмотра назад(?<=)
что соответствует одной цифре\d
.(?=\d)
использует утверждение положительного просмотра вперед(?=)
что соответствует одной цифре. Вы можете заменить это на(?=\d{3})
чтобы соответствовать 3 цифрам подряд после запятой.- Поскольку вы хотите заменить целевую запятую пустой строкой, вам не нужна строка замены.
Как правило, лучше использовать команды, которые работают с данными или файлами CSV. Однако, если ваши данные содержат запятые и вы не квалифицируете свой текст, может быть трудно отличить данные от разделителей. Если у вас есть четкий способ провести это различие, вам лучше использовать ConvertFrom-Csv для уже прочитанных данных или Import-Csv для файлов. Вам нужно будет определить заголовки либо в файлах, либо в команде.
РЕДАКТИРОВАТЬ
По моему мнению, ,
в наборе данных не разграничены, что приводит к тому, что этот ответ не работает должным образом, поскольку запятая рассматривается как разделитель столбцов при синтаксическом анализе CSV. Я собираюсь оставить его, поскольку он объясняет, как в целом управлять данными, как и следовало ожидать, если данные столбца были экранированным свойством. Однако ответ @AdminOfThings ниже должен работать для вашего конкретного случая здесь и исправит ошибочно определенный столбец, не полагаясь сначала на синтаксический анализ содержимого CSV как CSV.
Импортируйте данные с помощью Import-Csv
, затем удалите все ,
в третьем столбце. Это предполагает, что у вас нет значений, где,
это десятичный разделитель:
Если у вас есть заголовки в CSV, вам не нужно определять имена заголовков или увлекаться написанием CSV:
Import-Csv -Path \path\to\file.csv | Foreach-Object {
$_.ColumnName = $_.ColumnName -replace ','
} | Export-Csv -NoTypeInformation -Path \path\to\file.csv
Это работает так: мы импортируем CSV как рабочий PSCustomObject
, затем для каждой строки мы берем любое имя столбца с размером и удаляем ,
от него. Наконец, мы экспортируем измененныйPSCustomObject
вернуться к исходному CSV.
Если у вас нет заголовков, это становится немного сложнее, поскольку мы должны определять временные заголовки, но Export-Csv
нет возможности пропустить запись заголовков:
Import-Csv -Path \path\to\file.csv -Headers Col1, Col2, Col3, Col4, Col5, Col6, Col7 |
Foreach-Object {
$_.Col3 = $_.Col3 -replace ','
} | ConvertTo-Csv | Select-Object -Skip 1 |
Set-Content -Path \path\to\file.csv
Это делает то же самое, что и первый блок кода, но поскольку мы не хотим экспортировать временные заголовки, мы должны проявить творческий подход. Во-первых, обратите внимание, что мы ссылаемся на целевой столбец с временным именем заголовка. Вместо того, чтобы передавать измененный объект CSV прямо вExport-Csv
, сначала мы хотим преобразовать объект в CSV, используя ConvertTo-Csv
. Затем мы используемSelect-Object
чтобы пропустить первую строку преобразованного текста CSV, которая является заголовком, чтобы у нас были только данные строки и значения столбца. Наконец, мы используемSet-Content
чтобы записать текст CSV без заголовка обратно в исходный файл.