Классическая оболочка Cmd.exe в операционных системах Windows предоставляет очень простые средства для обработки текстов. Например, команда For /f позволяет читать строки текста из файла и обрабатывать их как одну строку, а оператор > дает возможность писать выходные данные команды в текстовый файл.

Однако простой построчный анализ текста дает сбой в том случае, если вам нужно обработать структурированные данные. Например, файлы в формате CSV являются чрезвычайно распространенным форматом обмена данными. Я не могу даже сосчитать, сколько раз видел в онлайн-форумах вопрос: «как мне прочитать вводимые данные из файла формата CSV, используя пакетный файл (то есть набор команд оболочки Cmd.exe)»? Возможно, вам пришлось делать весь анализ вручную, а это крайне сложно. Например, если строка вводимых данных содержит специальные символы, такие как < или >, вы не сможете выполнить анализ. Анализ файлов XML с помощью Cmd.exe даже более сложен. Если не сказать невозможен.

Windows PowerShell справляется с упомянутыми выше трудностями, предоставляя строку команд для импорта и экспорта структурированных данных. Все эти команды содержат в названии либо слово CSV, либо слово XML, поэтому вы можете получить их список, введя следующую команду в строке PowerShell:

Get-Command | Where-Object { ($_.Name -like "*csv*") или
($_.Name -like "*xml*") } | Select-Object Name

Когда вы запускаете эту команду, вы видите список всех команд в сессии PowerShell, которые содержат в названии либо слова CSV и XML, либо какие-то дополнительные имена. Я расскажу о командах, которые содержат глаголы Export и Import.

Импорт файлов CSV

Как уже говорилось выше, CSV – это весьма распространенный формат для обмена данными. файл CSV является открытым текстовым файлом, который представляет собой таблицу данных. Каждая строка файла — это одна запись (строка) данных. Первая строка файла обычно (хотя и не всегда) определяет имена полей (столбцов). Элементы данных внутри каждой строки разделены символом разделителя. В качестве разделителя часто используется запятая (особенно когда дело касается текстовых данных), поэтому элементы данных в файле CSV обычно заключены в двойные кавычки («) или в какие-либо другие символы. В таблице приведен пример таблицы данных.

 

Пример таблицы данных

На экране 1 показано, как эти данные будут представлены в файле CSV.

 

Пример данных файла CSV
Экран 1. Пример данных файла CSV

Import-Csv читает файл CSV и выводит список пользовательских объектов PowerShell: один для каждой строки вводимых данных. PowerShell воспринимает первую строку файла CSV как свойства объекта, а последующие строки файла являются выводимыми объектами. Например, если вы запускаете команду Import-Csv Sample.csv, то PowerShell выведет три объекта с двумя свойствами для каждого: DisplayName и Mail, как показано на экране 2.

 

Вывод при использовании Import-Csv для чтения файла CSV
Экран 2. Вывод при использовании Import-Csv для чтения файла CSV

Если файл CSV, который вы хотите импортировать, не имеет строки заголовка, вы можете использовать параметр –Header для наименования свойств объекта. Таким образом, если бы в Sample1.csv отсутствовала первая строка (заголовок), вы бы использовали команду, например:

Import-Csv Sample.csv -Header DisplayName,EmailAddress

Import-Csv использует символ запятой, так как это разделитель по умолчанию, но вы можете применить параметр –Delimiter для определения иного символа для разделителя. Например, если бы Sample.csv использовал символ «табуляции» в качестве разделителя, вы бы вводили такую команду:

Import-Csv Sample.csv -Delimiter "`t"

Поскольку Import-Csv выводит объекты PowerShell, вы можете задействовать другие команды PowerShell для обработки объектов. Например, предположим, что вы хотите рассортировать выводимые данные по критерию DisplayName, но вам нужно только свойство Mail для каждого объекта. Чтобы это сделать, вы используете команды Sort-Object и Select-Object:

Import-Csv Sample.csv | Sort-Object DisplayName |
Select-Object Mail

Также вы можете передать эти объекты команде ForEach-Object для обработки:

Import-Csv Sample.Csv | ForEach-Object {
'»{0}«<{1}>' -f $_.DisplayName,$_.Mail
}

Эта команда использует символ –f для вывода форматированной строки для каждого объекта и производит вывод данных, показанный на экране 3.

 

Чтение и обработка файла CSV командами Using?Import-Csv и ForEach-Object
Экран 3. Чтение и обработка файла CSV командами Using?Import-Csv и ForEach-Object

Экспорт файлов CSV

Иногда бывает необхоодимо создать файл CSV из выводимых данных объектов PowerShell. Чтобы это сделать, вы используете конвейер PowerShell для направления данных команде Export-Csv и указываете имя файла. PowerShell запишет выводимые данные объектов в файл CSV. Это просто, но есть одна небольшая хитрость. По умолчанию Export-Csv пишет строку, начинающуюся с символов #TYPE, в качестве первой строки файла CSV. Параметр –NoTypeInformation в Export-Csv опускает эту дополнительную строчку при выводе данных, поэтому я обычно указываю данный параметр.

Предположим, вы хотите создать копию Sample.csv, сортируя его по свойству DisplayName. Все, что вам нужно, — это импортировать файл, отправить его контент в команду Sort-Object, а затем экспортировать контент в новый файл CSV:

Import-Csv Sample.csv | Sort-Object DisplayName |
Export-Csv Sample-Sorted.csv –NoTypeInformation

Заметьте, что Export-Csv может выводить данные любых объектов PowerShell, а не только объектов, созданных при помощи Import-Csv. Например, взгляните на такую команду:

Get-ChildItem | Sort-Object Length |
Select-Object FullName,LastWriteTime,Length |
Export-Csv Data.csv -NoTypeInformation

Эта команда создает файл CSV, содержащий в текущей папке файлы, отсортированные по критерию размера. Эта команда использует Select-Object для выбора полного файлового имени каждого файла, времени последнего изменения и размера файла (длины). Таким образом, эти три свойства будут являться столбцами в файле CSV.

Импорт файлов XML

XML представляет собой другой тип текстового файла, который хранит структурированные данные. В листинге 1 приведен пример представления в XML данных из таблицы.

Данные в документе XML организованы в иерархическом порядке. В Sample.xml (листинг 1) у вас есть корневой элемент () и три дочерних элемента (). Элементы располагаются в парах и содержат другие элементы. Открывающий элемент использует угловые скобки вокруг своего имени, а закрывающий элемент использует косую черту перед именем элемента. Когда вы работаете с данными XML в PowerShell, вы должны иметь единственный корневой элемент. Другие элементы содержатся внутри корневого элемента.

В PowerShell есть команда Import-Clixml, но Import-Clixml не может импортировать Sample.xml, потому что Sample.xml не полностью соответствует формату, который требует cmdlet. Вместо него вы можете использовать Get-Content cmdlet и дополнительный тип обеспечения [Xml]: $Data = [Xml] (Get-Content Sample.xml).

После ввода команды переменная $Data содержит объект XmlDocument. Объект XmlDocument включает два свойства: xml (элемент в верхней части файла) и базу данных (корневой элемент). Вы можете вывести данные из файла XML так:

$Data.database.record

Эта команда производит точно такой же вывод данных, как показано на экране 2: выводит данные трех объектов с двумя свойствами для каждого (DisplayName и Mail).

Если данные файла XML, который вы хотите импортировать, были сохранены Export-Clixml, вам не нужен дополнительный акселератор типа [Xml] и команда Get-Content. Вместо них вы можете использовать Import-Clixml, о чем я расскажу в следующем разделе.

Экспорт Файлов XML

Вы можете экспортировать объект XmlDocument в файл, используя Export-Clixml. Как и Export-Csv, команда Export-Clixml требует имя файла. Рассмотрим такие команды:

$Data = [Xml] (Get-Content Sample.xml)
$Data | Export-Clixml Data.xml

Первая команда импортирует Sample.xml (листинг 1) в качестве объекта XmlDocument. Вторая команда экспортирует объект XmlDocument в Data.xml.

Import-Clixml противоположна Export-Clixml. Import-Clixml возвращает файл XML, который был экспортирован Export-Clixml в качестве объекта XmlDocument. Например, в следующей команде Import-Clixml возвращает Data.xml:

$Data2 = Import-Clixml Data.xml

После запуска этой команды переменная $Data2 содержит копию того же объекта XmlDocument, который хранится в $Data.

Помните, что вы можете применять команду Import-Clixml для импорта только файла XML, созданного Export-Clixml. Это связано с тем, что файл XML должен содержать специфический набор элементов, чтобы Import-Clixml могла импортировать его. Если файл XML не в нужном формате, вам необходимо использовать дополнительный акселератор типа [Xml] и Get-Content, о чем говорилось в предыдущем разделе.

Управляйте файлами CVS и XML

Текстовые файлы CSV и XML представляют собой популярные форматы для обмена данными. Создатели PowerShell предоставили нам несколько весьма мощных и простых в использовании команд, которые помогают импортировать и экспортировать файлы в оба формата. Выполняемый вручную анализ файлов CSV и XML остался в прошлом.

Листинг 1. Sample.xml




Garvin, Fred
fred.garvin@contoso.com


Flynn, Phineas
phineas.flynn@contoso.com


Bates, Gil
gil.bates@contoso.com