У меня есть CSV, содержащий более 24 000 имен серверов, а также другую информацию. Столбцы CSV - это Name
, Group
и Target
. Пример исходных данных для столбца «Имя»:
WindowsAuthServer @ wddg9028WIN
Я пытаюсь найти способ отредактировать столбец Name
в CSV. Мне нужно удалить WindowsAuthServer @
и WIN
из имен серверов. Единственное, что я хочу оставить, это имя сервера, или wddg9028
в этом примере. Потенциальная проблема заключается в том, что не каждое имя сервера имеет этот формат, а некоторые содержат только имя сервера. Очевидно, что те, которые уже верны, не нужно менять, но я не уверен, что это сбивает с толку.
Я пробовал делать:
$test = $file.Name -replace "WindowsAuthServer @ ",""
Это возвращает имена именно так, как я хочу (за вычетом удаления WIN). Однако всякий раз, когда я это делаю, я теряю все остальные столбцы из CSV.
Есть ли способ отредактировать один столбец в CSV? Следует ли это делать во время чтения данных в этом случае?
С большие наборы данных, Команда конвейерный обычно предпочтительнее для сохранения постоянного использования памяти:
Import-Csv in.csv |
Select-Object @{
n='Name'
e = { $_.Name -creplace 'WindowsAuthServer @ |WIN' }
}, Group, Target |
Export-Csv -NoTypeInformation -Encoding Utf8 out.csv
Таким образом, данные обрабатываются строка за строкой, и в качестве бонуса вы можете использовать Select-Object
с расчетное свойство для выполнения преобразования вашего имени.
Тем не менее, если производительность имеет значение и, вы знаете, что можете разместить все данные в памяти сразу, вы можете использовать следующее (PSv4 +):
# Read the file in full into memory (transformed into objects).
$file = Import-Csv in.csv
# Modify the `.Name` property values of the in-memory object collection.
$file.ForEach({ $_.Name = $_.Name -creplace 'WindowsAuthServer @ |WIN' })
# Export the in-memory object collection back to a CSV file.
$file | Export-Csv -NoTypeInformation -Encoding Utf8 out.csv
Что касается что ты пробовал:
$test = $file.Name -replace "WindowsAuthServer @ ",""
Этот оператор выполняет замену строк для всех значений свойств .Name
и возвращает преобразованные строки как новые струны (которые вы затем назначаете $test
).
Следовательно, ваши значения $file.Name
остаются неизменный.
Вместо этого необходимо явно обновить свойства .Name
.
Хотя может возникнуть соблазн сделать следующее, нет работает:
# !! Does NOT work if $file is an *array* of objects.
$file.Name = $file.Name -replace "WindowsAuthServer @ ",""
То есть, хотя вы можете получить значения свойств массива объектов с простым доступом к свойству (.Name
) - функция, называемая перечисление участников - свойства параметр, которые по дизайну не поддерживаются - см. эта проблема GitHub.
Вместо этого, помимо использования конвейера, как показано выше, у вас есть два варианта:
в PSv4 + вы можете использовать метод сбора .Where()
, как показано выше.
в качестве альтернативы (также работает в более низких версиях PS) используйте цикл foreach
, как показано в Ответ Ансгара Вихерса.
Пара тысяч строк с 3 полями в каждой - это далеко не то, что я бы назвал большим набором данных. ;)
@AnsgarWiechers: Ну, пара тысяч десять, но точка взята. Я надеюсь, что сопоставление этих двух подходов по-прежнему полезно.
Импортируйте CSV. Обработайте строки в цикле, заменив текущее значение рассматриваемого поля измененным значением. Экспортируйте данные обратно в CSV.
$csv = Import-Csv 'C:\path\to\input.csv'
foreach ($row in $csv) {
$row.Name = $row.Name -replace 'WindowsAuthServer @ '
}
$csv | Export-Csv 'C:\path\to\output.csv' -NoType
По крайней мере, это ваш третий вопрос по теме. Найдите руководство по PowerShell. Это базовый материал В самом деле.
Спасибо, это то, что я искал. Я не уверен, почему, когда я пробовал $ row.Name = $ row.Name ... ранее, это не сработало. Может быть, я использовал двойные кавычки вместо одинарных?
Нет, в данном случае двойные кавычки не должны иметь никакого значения.
@ JK72: $row.Name = $row.Name...
работает, только если $row
является строкой не замужем, как в этом ответе. Напротив, если $file
содержит строки все, как следует из вашего вопроса, $file.Name = $file.Name...
выполняет работу нет
Сегодня вы задали этот же вопрос три раза.