Войти

Показать полную графическую версию : Форматирование заголовка *.csv файла


maslinaV
23-09-2017, 10:15
Здравствуйте.

Необходимо редактирование csv заголовка.
Пример файла Excel прикреплен.

Вот как выглядит файл Excel


ou2 ou1 dc2 dc1 mail ou3 ou4 dc2 dc1 principal
user user Семен Астахов office astachov@mail.ru user stack Семен Астахов office s.astachov
user user Александр Пушкин office pushkin@mail.ru user stack Александр Пушкин office a.pushkin
user user Антон Чехов office checov@mail.ru user stack Антон Чехов office a.chechov

В файле Excel составляются поля и в них заносятся данные

Затем происходит конвертация в формат *csv.
Затем файл формата *csv. импортируется и начинается форматирование

Вот скрипт



clear

# данный скрипт импортирует файл .*csv, добавляет кавычки значениям в нужных полях
# и затем обратно экспортирует в .*csv

Function set-pause{

PARAM (
[PARAMETER(Mandatory=$false,
HelpMessage = "Укажите сообщение для паузы"
)
]$message


)


Read-Host $message
}

$mes = " Cкрипт ставиться на паузу"

$name_x = "d:\script-ps\sample.xlsx"
$name_c = "d:\script-ps\sample.csv"
$name_out = "d:\script-ps\sample-out.csv"

$oExcel = New-Object -ComObject "Excel.Application"
$oExcel.DisplayAlerts = $false
$oWorkbook = $oExcel.Workbooks.Open("$name_x")
$oWorkbook.Sheets.Item("Лист1").SaveAs("$name_c",6)
$oWorkbook.Close($false)
$oExcel.Quit()

#импорт *.csv с кодировкой по умолчанию (в системе - кодировка Windows-1251)
Import-Csv $name_c -Encoding Default -Delimiter ',' |
# перебор все данных в полученном массиве

ForEach-Object -begin {
$str = Get-Content $name_c -First 1 # шапка csv
$a = $str -split ',' # массив имен объектов
$str += "`n" # данные пишутся со следующей строки
} -process {
$str += [String]::Format(
"`"OU = {0},OU = {1},DC = {2},DC = {3}`";{4};`"OU = {5},OU = {6},DC = {7},DC = {8}`";{9};`n",$_."$($a[0])", $_."$($a[1])", $_."$($a[2])", $_."$($a[3])",$_."$($a[4])",$_."$($a[5])", $_."$($a[6])", $_."$($a[7])", $_."$($a[8])",$_."$($a[9])")
} -end { $str | Out-File $name_out -Encoding Default -Force }

# -begin {...} - блок скрипта, который будет запущен перед обработкой первого объекта ввода
# Get-Content .\sample.csv -First 1 - читает только шапку содержимого указанного файла
# $str - в этой переменной содержится обрабатываемая строка в текуший момент
# -First 1 - этот параметр сообщает оболочке PowerShell, что необходимо выбрать первый объект из этого списка.
# -split - Оператор split рабивает исходную строку на части и возвращает массив строк.
# Граница, по которой производится разбиение, указывается с помощью
# регулярного выражения.
# += - опреатор присваивания
# $str += "`n" к строке содержащейся в $str в текущий момент добавляется
# управляющий символ и затем $str присваивается уже эта видоизменнная строка и
# и передается в блок команд -process {...}

# -process {...} - блок скрипта, применяемый к каждому входному объекту
# $str += - в данном выражении строка сначала форматируется нужным образом, а затем
# присваивается обратно переменной $str в уже измененном виде
# ` - экранирующий символ, чтобы кавычаи интепретрировались как текст

# Format - статический метод форматирования
# [String]::Format() - композитное форматирование
# Метод Format класса String - возвращает объект строки.
# Т.е. он передает возвращаемую им строку по конвейеру Windows PowerShell
# Команда содержит элемент форматирования с индексом 0, соответствующим первому объекту в списке.
# $_."$($a[1])" - это динамическая переменная, в текущей момент времени она содержит
# значение какой-то строки 2-го поля, обрабатываемого файла *.csv и помещает это значение в кавычки
# и т.д

# -End{...} - запускается после обработки последнего объекта ввода
# здесь уже текущая обработанная строка передается по конвейру и экспортируется в файл *.csv






Получается *csv. такого вида



ou2,ou1,dc2,dc1,mail,ou4,ou3,dc4,dc3,principal
"OU = user,OU = user,DC = Семен Астахов,DC = office";astachov@mail.ru;"OU = user,OU = stack,DC = Семен Астахов,DC = office";s.astachov;
"OU = user,OU = user,DC = Александр Пушкин,DC = office";pushkin@mail.ru;"OU = user,OU = stack,DC = Александр Пушкин,DC = office";a.pushkin;
"OU = user,OU = user,DC = Антон Чехов,DC = office";checov@mail.ru;"OU = user,OU = stack,DC = Антон Чехов,DC = office";a.chechov;


Здесь проблема отформатировать заголовок и привести его к такому виду

ou2,ou1,dc2,dc1 – заменяется на DN
ou4,ou3,dc4,dc3 – заменяется на СN

Тогда файл *.csv должен быть таким

DN,mail,CN,principal
"OU = user,OU = user,DC = Семен Астахов,DC = office";astachov@mail.ru;"OU = user,OU = stack,DC = Семен Астахов,DC = office";s.astachov;
"OU = user,OU = user,DC = Александр Пушкин,DC = office";pushkin@mail.ru;"OU = user,OU = stack,DC = Александр Пушкин,DC = office";a.pushkin;
"OU = user,OU = user,DC = Антон Чехов,DC = office";checov@mail.ru;"OU = user,OU = stack,DC = Антон Чехов,DC = office";a.chechov;


p.s
Длинные куски кода (там где команда Format) пробовал перенести символом ` , но тогда на выходе в файл *.csv
записывается текст с переносом. Если знаете как правильно перенести длинный код подскажите.
Спасибо.

Busla
23-09-2017, 11:52
Тогда файл *.csv должен быть таким »
не должен - у вас в основной части разделитель - «;», а в заголовке почему-то «,»

Здесь проблема отформатировать заголовок и привести его к такому виду»
ваш скрипт умеет работать только с единственным форматом данных, поэтому не нужно ничего форматировать и приводить - просто впишите строку, какой она должна быть в файле:
$str = Get-Content $name_c -First 1 # шапка csv
$a = $str -split ',' # массив имен объектов
$str = 'DN;mail;CN;principal'
$a = 'ou2,ou1,dc2,dc1,mail,ou3,ou4,dc2,dc1,principal' -split ','


Длинные куски кода (там где команда Format) пробовал перенести символом ` , но тогда на выходе в файл *.csv
записывается текст с переносом. Если знаете как правильно перенести длинный код подскажите. »
по всей видимости вы не код разбивали на строки, а строковую константу

maslinaV
23-09-2017, 12:35
не должен - у вас в основной части разделитель - «;», а в заголовке почему-то «,» »
Если в заголовке будет " ; " тогда при импорте атрибутов через csdve в AD Win 2003 будет ошибка
Я вручную готовил *.csv и поля заголовка разделял , - тогда импорт без ошибок

Busla
23-09-2017, 14:57
maslinaV, для csvde у вас все разделители должны быть запятыми, а не только заголовок
сейчас у вас это работает из-за ошибки в csvde :-)

maslinaV
23-09-2017, 15:10
Вот переделанный кусок кода
Там в строковой константе я по ошибке использовал ";" , я переделал

Вот кусок кода

ForEach-Object -begin {

$str = 'DN,mail,CN,principal'
$a = 'ou2,ou1,dc2,dc1,mail,ou3,ou4,dc2,dc1,principal' -split ','
#$str = Get-Content $name_c -First 1 # шапка csv
#$a = $str -split ',' # массив имен объектов
$str += "`n" # данные пишутся со следующей строки
} -process {
$str += [String]::`
Format(
"`"OU = {0},OU = {1},DC = {2},DC = {3}`",{4},`"OU = {5},OU = {6},DC = {7},DC = {8}`",{9}`n",$_."$($a[0])", $_."$($a[1])", $_."$($a[2])",$_."$($a[3])",$_."$($a[4])",$_."$($a[5])",$_."$($a[6])", $_."$($a[7])", $_."$($a[8])",$_."$($a[9])"
)
} -end { $str | Out-File $name_out -Encoding Default -Force }

А вот что мне надо было получить на выходе



DN,mail,CN,principal
"OU = user,OU = user,DC = Семен Астахов,DC = office",astachov@mail.ru,"OU = stack,OU = user,DC = Семен Астахов,DC = office",s.astachov
"OU = user,OU = user,DC = Александр Пушкин,DC = office",pushkin@mail.ru,"OU = stack,OU = user,DC = Александр Пушкин,DC = office",a.pushkin
"OU = user,OU = user,DC = Антон Чехов,DC = office",checov@mail.ru,"OU = stack,OU = user,DC = Антон Чехов,DC = office",a.chechov


Что и получилось.

Я действительно пытался в стороковой константе сделать перенос, так как не удобно
читать длинный код, а разве для строковых констант нет возможности оформить перенос для удобочитаемости кода ?

Как оформлю все это в функцию, попробую выложить результат.

Busla
23-09-2017, 18:01
maslinaV, можно разбить строку на несколько, и их конкатенировать
только это не особо повлияет на удобочитаемость, потому что шаблон а одной части, а подстановочные переменные - в другой

У меня вообще совершенно всё вызывает недоумение:
Я бы или с файлами работал чисто на уровне текста с пребразованием строки регулярным выражением, либо импорт в структуру данных, её преобразование, экспорт.
Но зачем весь этот csv, если можно напрямую взять данные из excel и записать в AD. И csvde на момент выхода win 2k3 уже считался устаревшим и недостаточно функциональным - что потом делать с этой прорвой беспарольных учёток?
И формат данных в excel сомнительный. И вообще - откуда он, и что первично? Если руками забивает кто-то - так не проще ли сразу дать ограниченный доступ на заведение учёток и пользоваться штатными инструментами - там это нагляднее. И я ещё удивился: кто такой Чечов? - зачем эти извращения с транслитом?




© OSzone.net 2001-2012