Как изменить значения импортированной переменной CSV с помощью PowerShell
Приведенный ниже сценарий является примером того, как я импортирую файл CSV, пытаюсь отредактировать одно из значений, а затем проверяю значение.
$Animal_Farm = Import-CSV "Test.csv"
Echo "The Data"
$Animal_Farm
Echo "`n`n`n"
Echo "Dog's Status"
$Animal_Farm.Status[1]
Echo "`n`n`n"
Echo "Updating Dog's Status to Employed"
$Animal_Farm.Status[1] = "Employed"
Echo "`n`n`n"
Echo "Dog's Status"
$Animal_Farm.Status[1]
Это выходные данные, данные не изменились, а статус Dog по-прежнему Redundant.
The Data
Animal Ocupation Status
------ --------- ------
Cat Construction Employed
Dog Professional Redundant
Rat GP Employed
Dog's Status
Redundant
Updating Dog's Status to Employed
Dog's Status
Redundant
Как редактировать импортированные данные? Мой план состоит в том, чтобы передать измененные данные в файл JSON.
Это содержимое файла CSV
Animal,Ocupation,Status
Cat,Construction,Employed
Dog,Professional,Redundant
Rat,GP,Employed
2 ответа
содержит массив объектов, каждый из которых имеет свойство.
Когда вы просите PowerShell разрешить
$Animal_Farm.Status
, PowerShell говорит: «Да, у массива нет свойства, позвольте мне создать новый массив из
Status
значения свойств каждого элемента в массиве», что вы в конечном итоге индексируете с помощью
$Animal_Farm.Status[1]
.
Чтобы обратиться к свойствам одного из базовых элементов в исходном массиве, используйте оператор индекса непосредственно на
$Animal_Farm
вместо:
$Animal_Farm[1].Status
Чтобы дополнить полезный ответ Матиаса Р. Джессена концептуальной информацией:
Как утверждает Матиас, доступ к свойству () в коллекции (массиве) объектов () автоматически возвращает значения свойств элементов коллекции в массиве [1] (при условии, что коллекция сама по себе не имеет свойства с таким именем, в в этом случае последний имеет приоритет).
Эта функция, которая также работает с методами, называется перечислением элементов и более подробно объясняется в этом ответе .
Однако перечисление элементов не поддерживает присвоение свойств :
Если вы пробовали что-то вроде
- Несмотря на неожиданное сообщение об ошибке ( технически правильное), эта невозможность присвоить (по определению унифицированное ) значение заданному свойству всех отдельных элементов коллекции является преднамеренным .
- В отличие от этого, вызов изменяющего метода через перечисление членов (если доступно ) возможен.
- Для получения дополнительной информации см. этот ответ и выпуск GitHub № 5271.
Если вы попытаетесь присвоить значение свойства с помощью индексации (
Причина в том, что
возвращает массив значений свойств , которые больше не связаны с объектами, из которых они были получены , и хотя вы можете технически изменить этот массив, присваивая его элементам, измененный массив просто отбрасывается после оператора присваивания, учитывая, что он не захвачен в любом месте.
Вкратце: вы по ошибке изменяете временный массив .Напротив, применение индекса к самой коллекции (
для возврата второго объекта , хранящегося в коллекции) возвращает ссылку на объект , свойство, которое вы затем можете эффективно изменить ( )
Упрощенный пример :
# Create a 2-element sample array.
$animals = [pscustomobject] @{ Animal = 'Cat'; Status = 'Employed' },
[pscustomobject] @{ Animal = 'Dog'; Status = 'Redundant' }
# Trying to set the status of ALL animals via member enumeration
# CAUSES AN ERROR, because it isn't supported:
# InvalidOperation: The property 'Status' cannot be found on this object. [...]
$animals.Status = 'Employed' # !! ERROR
# Trying to set the status of ONE animal via member enumeration is
# QUIETLY IGNORED:
# * What is being modified is a *temporary array* of property values.
# * Therefore, $animals.Status[1] is still 'Redundant' after this statement.
$animals.Status[1] = 'Employed' # !! QUIETLY IGNORED
# OK: Avoid member enumeration, and index directly into the collection
# to get the animal object of interest, then set its property:
$animals[1].Status = 'Employed' # OK
[1] Технически массив значений возвращается только в том случае, если входная коллекция состоит из двух или более элементов; для одноэлементной коллекции значение свойства одного элемента возвращается как есть. Другими словами: перечисление членов ведет себя как конвейер PowerShell ; см. этот ответ и этот ответ для примеров связанных ловушек и выпуск GitHub № 6802 для обсуждения этого, возможно, удивительного поведения.