Форум программистов, компьютерный форум, киберфорум
PowerShell
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/35: Рейтинг темы: голосов - 35, средняя оценка - 4.69
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
1

Скрипт замены баз в файле ibases.v8i c использованием excel

12.09.2019, 09:14. Показов 6511. Ответов 19

Author24 — интернет-сервис помощи студентам
Добрый день.
Помогите пожалуйста как сделать замену всех путей баз в файлах ibases.v8i.
Есть сервер, где у кого-то прописаны в файле базы, и эти базы переехали, а поправить нужно у всех, у кого в файле ibases.v8 прописаны старые базы. на новые. При этом новые базы и название старых нужно взять из excel файла.

Я предполагаю действовать следует так
1. Последовательно прочитать все файлы "C:\users\*\appdata...\ibases.v8i"
2. Прочитать базы подлежащие замене из cvs файла, в котором есть поля: "СтарыйСервер","СтароеНазваниеБазы","НовыйСервер","НовоеНазваниеБазы"
2a - учесть ситуацию, когда неизвестно какой указан сервер. То есть может быть что угодно между:
Connect=Srvr="Тутнепонятночто";Ref="base1";
3. Скопировать файлы перед изменением с сохранением структуры у кого производилось изменение (например пользователь user1) - значит в папке backup создать папку с именем User1 и уже туда скопировать.
3. Произвести замену по маске пути на новую базу.
4. Сохранить изменение в исходный файл ibases.v8i

Моё решение промежуточное:
1. Создан файл excel, с последующим сохранением в cvs с указанными значениями выше.
Кликните здесь для просмотра всего текста
Мой код:
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
$replacers = Import-Csv "C:\ps\test1.csv" -Encoding Default -Delimiter ";"
gc C:\ps\ibases.v8i | ForEach-Object {
   $output = $_
   foreach ($r in $replacers) {
     
     $outSrvr='Connect=Srvr="'+$r.Srvr+'";'
     $outRef='Ref="'+$r.Ref+'";'
     $outReplace=$outSrvr+$outRef        
     $output = $output -replace ("^Connect=Srvr=.+[$r.Ref$]??"),($outReplace)
 
   }
   return $output | Out-File C:\ps\ibases11.v8i -Append -Encoding utf8
}


Содержимое файла ibases.v8i Для примера:
Кликните здесь для просмотра всего текста

[База1]
Connect=Srvr="server1";Ref="Base1";
ID=7853661-7598-49778-3gg6-1414451
OrderInList=7859
Folder=/
OrderInTree=458
External=0
App=Auto
WA=1
[База2]
Connect=Srvr="server2";Ref="Base2";
ID=7853661-7598-49778-3gg6-1414551
OrderInList=45889
Folder=/
OrderInTree=78
External=0
ClientConnectionSpeed=Normal
App=Auto
WA=1
Version=8.3
DefaultVersion=8.3.12.1616
[abk _ 2017]
Connect=Srvr="Server3";Ref="Base3";
ID=7853661-7598-49778-3gg6-14148551
OrderInList=4586
Folder=/
OrderInTree=1458
External=0
ClientConnectionSpeed=Normal
App=Auto
WA=1
Version=8.3




Я запутался как сделать регулярное выражение для замены и если выполнять выше код, замена происходит, но например в файле cvs будет последняя база base3, то ВСЕ базы будут замены почему то на base3 и server3
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
12.09.2019, 09:14
Ответы с готовыми решениями:

Редактирование баз в ibases.v8i
Всем привет! Нужна помощь со скриптом который будет дописывать (с проверкой существования) базы...

Скрипт поиска и замены текста в файле
Всем привет! Помогите пожалуйста написать простой скрипт по поиску и замены текста в файле. Есть...

Скрипт замены в текстовом файле с файлом замен в цикле
Добрый день всем! Нужно произвести замену в плейлистах .m3u (по сути текстовые файлы). Но так как...

Самый простой и РАБОТАЮЩИЙ скрипт для замены текста в файле
Очень плохо разбираюсь в этих скриптах, надеюсь на понимание....

19
419 / 179 / 27
Регистрация: 11.03.2018
Сообщений: 764
12.09.2019, 09:56 2
А зачем построчный цикл файла ibases.v8i ?
Тебе нужен побазный цикл, по секциям в смысле ( [База1], [База2] )
0
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
12.09.2019, 10:03  [ТС] 3
Я ведь не знаю как могут называться все строчки в файле или блоки. Я лишь знаю что есть база, которую нужно править:
Connect=Srvr="server1";Ref="Base1";
А может там будет:
Connect=Srvr="1server1";Ref="Base1";

Сложность ещё заключается в том, что название старых серверов (если нет то неизвестное название) и самих баз нужно указывать в excel.

Если подскажите Ваш вариант, буду признателен любой помощи. Всё равно ведь даже в блоках замена будет через replace
0
419 / 179 / 27
Регистрация: 11.03.2018
Сообщений: 764
12.09.2019, 10:06 4
Иными словами, по-хорошему нужна ещё функция чтения ini-файла в обьект. Такие есть уже готовые.
0
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
12.09.2019, 10:24  [ТС] 5
Это ведь не ini файл. тут не сделать так:
PowerShell
1
2
3
4
$Ini = Get-Content -Path $FileF | Where-Object { $_ -match 'КаталогПрием=' }
[array]$ContentF=""
$ContentF[0] = $Ini.Split('=')[1]
$ContentF_Change = $ContentF.Replace('%username%','CF\%username%\')
Какие например блоки предлагаете? пример можно адаптированный под мои условия? потому что я не понимаю что именно хотите

Добавлено через 10 минут
У меня важный вопрос как сделать замену ещё т.к. не пойму какую маску сделать для:
1: Connect=Srvr="НЕИЗВЕСТНОЧТО";Ref="Base1";
2: Connect=Srvr="из файла название сервера старого";Ref="Base1";
0
419 / 179 / 27
Регистрация: 11.03.2018
Сообщений: 764
12.09.2019, 10:33 6
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
function Parse-IniFile ($file)
{
  $ini = @{}
  switch -regex -file $file
  {
    #Section.
    "^\[(.+)\]$"
    {
      $section = $matches[1].Trim()
      $ini[$section] = @{}
      continue
    }
    #Int.
    "^\s*([^#].+?)\s*=\s*(\d+)\s*$"
    {
      $name,$value = $matches[1..2]
      $ini[$section][$name] = [int]$value
      continue
    }
    #Decimal.
    "^\s*([^#].+?)\s*=\s*(\d+\.\d+)\s*$"
    {
      $name,$value = $matches[1..2]
      $ini[$section][$name] = [decimal]$value
      continue
    }
    #Everything else.
    "^\s*([^#].+?)\s*=\s*(.*)"
    {
      $name,$value = $matches[1..2]
      $ini[$section][$name] = $value.Trim()
    }
  }
  $ini
}
0
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
12.09.2019, 10:41  [ТС] 7
Почему то мне кажется это не то направление т.к.
1. Требуется знать название блоков что эта функция выдает на name
2. потом придется пытаться получить содержимое для замены строчки через такое например: ((Parse-IniFile)."что-то").connect.
3. и ведь потом это всё возвращать в исходный файл с другой структурой.
4. Хорошо, получили мы: ту же самую строчку, в которой нужно произвести замену: Connect=Srvr="НЕИЗВЕСТНОЧТО";Ref="Base1";

и снова на том же месте что и я сейчас
0
419 / 179 / 27
Регистрация: 11.03.2018
Сообщений: 764
12.09.2019, 10:58 8
PowerShell
1
2
3
4
5
6
7
8
9
10
11
#USAGE:
 
$ini = Parse-IniFile ./ibases.v8i 
 
foreach ( $section in $ini.keys ) {
   
  ...
   $ini.$section.Connect
  ...
 
}
Добавлено через 14 минут
Я, разумеется, не вникал конкретно, что у тебя там.
Просто методологически, если надо изменить значения в конфиг. файле,
его надо сначала разобрать на обьекты, а затем пройтись по нему с помощью подходящего итератора.
0
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
12.09.2019, 11:21 9
Цитата Сообщение от dj-12l Посмотреть сообщение
Помогите пожалуйста как сделать замену всех путей баз в файлах ibases.v8i.
Есть сервер, где у кого-то прописаны в файле базы, и эти базы переехали, а поправить нужно у всех, у кого в файле ibases.v8 прописаны старые базы. на новые.
А вы не слышали про такое решение:

1. Всем пользователям в профиль копируется (лучше групповой политикой) файл - 1CEStart.cfg

"$env:USERPROFILE\AppData\Roaming\1C\1CEStart\1CEStart.cfg"

В этом файле пишется одна строчка:

Код
CommonInfoBases=\\dfsroot\share\1C\Bases\ib_common.v8i
2. В файле ib_common.v8i, расположенном на сетевой (лучше dfs) шаре, перечисляете все нужные базы и свойства подключения.

Всё. Теперь изменив список баз в одном сетевом файле, все пользователи при запуске 1С-клиента получат новые настройки.
0
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
12.09.2019, 11:41  [ТС] 10
Да, про такой вариант решения я знаю. Только сложность в том что другие пользователи не должны знать у кого какие базы. Баз тысячи! А так получается все будут видеть их.

У многих есть специальный ярлык с отображением баз куда у них есть доступ. Но вот много у кого по старому записано в файл v8i.

Прошу помочь с вариантом перебрать все файлы у всех пользователей C:\users ...\ibases.v8i на предмет замены из excel файла.
Хотя бы составить маску т.к. уже голова кипит т.к. не отрабатывает replace или заменят всё по последнему значению в файле cvs.

Добавлено через 11 минут
я понимаю что если через dfs, то можно скрывать не нужную информацию у кого нет доступа. Но вопрос в том, что сейчас требуется именно вручную отредактировать файлы, а их очень много. поэтому такой метод решения и остается. И поменять политику выведения списка я не смогу
0
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
12.09.2019, 11:48 11
Цитата Сообщение от dj-12l Посмотреть сообщение
сложность в том что другие пользователи не должны знать у кого какие базы. Баз тысячи! А так получается все будут видеть их.
Сделайте для разных групп пользователей разные ib_common.v8i (доступные только им). Этим же группам распространяйте соответствующий 1CEStart.cfg.

Цитата Сообщение от dj-12l Посмотреть сообщение
уже голова кипит т.к. не отрабатывает replace
Настройте все один раз нормально и больше не придётся заниматься кипучей деятельностью...

Добавлено через 3 минуты
Цитата Сообщение от dj-12l Посмотреть сообщение
я понимаю что если через dfs, то можно скрывать не нужную информацию у кого нет доступа.
Для этого вовсе не обязательно DFS (ABE) и даже без NTFS ACL можно обойтись, достаточно даже простых share permissions...
0
419 / 179 / 27
Регистрация: 11.03.2018
Сообщений: 764
12.09.2019, 11:52 12
Цитата Сообщение от KDE777 Посмотреть сообщение
Настройте все один раз нормально
Ну ты замахнулся)) Это ж краеугольный камень человеческой жизнедеятельности;
сначала способ <<черезжопу>> оформляется в качестве правила или закона, а затем все последующие поколения занимаются неизбежной кипучей деятельностью.
0
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
12.09.2019, 12:00  [ТС] 13
Цитата Сообщение от KDE777 Посмотреть сообщение
Настройте все один раз нормально и больше не придётся заниматься кипучей деятельностью...
Я согласен, что такой вариант хороший!
У нас есть специальный ярлык что отображает нужные базы пользователю и переезды не страшны. Но сейчас нет возможности это сделать, а есть сотни людей у которых нужно заменить базы и прав у меня на групповые политики нет. Поэтому подскажите хотя бы, какую маску использовать для замены? Как гуру регулярных выражений.

В будущем да, надеюсь мы всех перевеедем, но сейчас нужно выйти из ситуации т.к. очень большие объемы.

Если требуется, я сделаю прям полный комплект для примера с cvs
0
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
12.09.2019, 13:26 14
Цитата Сообщение от dj-12l Посмотреть сообщение
Я запутался как сделать регулярное выражение для замены и если выполнять выше код, замена происходит, но например в файле cvs будет последняя база base3, то ВСЕ базы будут замены почему то на base3 и server3
PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$v8i_path = 'C:\Temp\1CEStart'
$csv_list = "C:\Temp\1CEStart\new_1c_bases.csv"
 
$base_list = Import-Csv -Path $csv_list -Delimiter ';' -Encoding Default
 
ForEach ($v8i_file in Get-ChildItem -Path $v8i_path\*.v8i -File)
{
    $config = Get-Content -Path $v8i_file -Encoding UTF8
    
    ForEach ($base in $base_list)
    {
        $Pattern = "^Connect=Srvr=.+;Ref=`"$($base.СтароеНазваниеБазы)`";$"
        $config = $config -replace $Pattern,"Connect=Srvr=`"$($base.НовыйСервер)`";Ref=`"$($base.НовоеНазваниеБазы)`";"
    }
 
    $config | Set-Content -Path $v8i_file -Encoding UTF8
}
0
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
12.09.2019, 14:32  [ТС] 15
Цитата Сообщение от KDE777 Посмотреть сообщение
$Pattern = "^Connect=Srvr=.+;Ref=`"$($base.СтароеНазваниеБазы)`";$"
Что требуется указать что если неизвестно старое название?
или в exel написать в ячейке .+?

Добавлено через 10 минут
Возможно ли сделать копию файла именно только где производилась замена или нет? условие что есть что заменить через Match?
0
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
12.09.2019, 14:34 16
Цитата Сообщение от dj-12l Посмотреть сообщение
Что требуется указать что если неизвестно старое название?
тогда это бессмысленная задача, т.к. под шаблон:

Код
Connect=Srvr="ServerName";Ref=".+";
попадут все подключения.
0
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
12.09.2019, 14:44  [ТС] 17
Цитата Сообщение от KDE777 Посмотреть сообщение
тогда это бессмысленная задача, т.к. под шаблон:
Согласен.
Я думал вы сделали еще проверку старого сервера, но как сделали пойдет и хорошо.

Насколько понял, требуется указать $v8i_path = 'C:\users'
и он пройдет по всем папкам пользователей?

2.Возможно ли сделать backup тех файлов v8i, что будут изменяться.
Я подумал может сделать условие $Pattern = "^Connect=Srvr=.+;Ref=`"$($base.СтароеНазваниеБазы)`";$" - Matсh, то тогда если истинно, сделать item-copy, перед заменой. с сохранением структуры оригинального файла - то есть если нашелся файл в c:\users\ivanov\1cstart\v8i То и бэкап сделать в папку указанную в переменной другой c:\backup\users\ivanov - чтобы найти можно было изменения, а то мало ли не такй что пойдет в замене
0
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
12.09.2019, 15:12 18
Лучший ответ Сообщение было отмечено dj-12l как решение

Решение

Цитата Сообщение от dj-12l Посмотреть сообщение
Насколько понял, требуется указать $v8i_path = 'C:\users'
и он пройдет по всем папкам пользователей?
Нет так показанный выше скрипт не сработает.

Цитата Сообщение от dj-12l Посмотреть сообщение
Возможно ли сделать backup тех файлов v8i, что будут изменяться.
Конечно возможно, в чём именно возникли сложности?

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$users_path = 'C:\Users'
$csv_list   = '\\server\share\new_1c_bases.csv'
 
$base_list = Import-Csv -Path $csv_list -Delimiter ';' -Encoding Default
 
ForEach ($v8i_file in Get-ChildItem -Path $users_path -Directory | Get-ChildItem -Path {"$($_.FullName)\AppData\Roaming\1C\1CEStart\*.v8i"} -ErrorAction SilentlyContinue -File)
{
    $save   = $false
    $config = Get-Content -Path $v8i_file -Encoding UTF8
    
    ForEach ($base in $base_list)
    {
        $Pattern = "^Connect=Srvr=.+;Ref=`"$($base.СтароеНазваниеБазы)`";$"
 
        if ($config -match $Pattern)
        {
            $config = $config -replace $Pattern,"Connect=Srvr=`"$($base.НовыйСервер)`";Ref=`"$($base.НовоеНазваниеБазы)`";"
            $save = $true
        }
    }
 
    if ($save)
    {
        Copy-Item -Path $v8i_file -Destination "$($v8i_file.FullName).bak"
        $config | Set-Content -Path $v8i_file -Encoding UTF8
    }
}
0
85 / 1 / 0
Регистрация: 22.02.2016
Сообщений: 103
12.09.2019, 16:18  [ТС] 19
О, круто. Вроде как работает! Спасибо.
вообще я имел ввиду в отдельно место скопировать файл т.к. как потом поймешь у кого требовалось заменять, а у кого нет?
или может записать в файл лог у кого производилась замена. например

PowerShell
1
2
3
4
5
6
 if ($save)
    {
        Copy-Item -Path $v8i_file -Destination "$($v8i_file.FullName).bak"
        $config | Set-Content -Path $v8i_file -Encoding UTF8
        ($v8i_file.FullName) | set-content c:\backup\log.txt
    }
0
1886 / 1108 / 428
Регистрация: 22.01.2016
Сообщений: 3,050
12.09.2019, 16:41 20
Цитата Сообщение от dj-12l Посмотреть сообщение
вообще я имел ввиду в отдельно место скопировать файл
Делайте. Думаю, что от реализации копирования файлов средствами PS у вас ничего не закипает

Цитата Сообщение от dj-12l Посмотреть сообщение
или может записать в файл лог у кого производилась замена
А можно, до изменения, копировать все v8i-файлы в один каталог, добавляя к названию имя профиля (пользователя):

PowerShell
1
2
3
4
ForEach ($v8i_file in Get-ChildItem -Path $users_path -Directory | Get-ChildItem -Path {"$($_.FullName)\AppData\Roaming\1C\1CEStart\*.v8i"} -ErrorAction SilentlyContinue -File)
{
    Copy-Item -Path $v8i_file.FullName -Destination "c:\backup\$(($v8i_file.FullName -split '\\')[2])_$($v8i_file.Name)"
}
Добавлено через 4 минуты
Цитата Сообщение от dj-12l Посмотреть сообщение
($v8i_file.FullName) | set-content c:\backup\log.txt
1. Тут не нужны скобки
2. Вместо Set-Content, используйте Add-Content иначе в log.txt получите только одну запись, т.к. при изменение каждого v8i-файла log.txt будет перезаписан.
0
12.09.2019, 16:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.09.2019, 16:41
Помогаю со студенческими работами здесь

Изменить текст в одном txt-файле с использованием двух других для поиска и замены строк
Здравствуйте, подскажите, пожалуйста как можно заменить текст в одном тхт файле... список того, что...

Bash - скрипт для бэкапа баз Mysql
Решил попробовать написать скрипт бакапа баз Mysql нашел команду бакапа одной базы mysqldump...

Сравните пожалуйста операторы ветвления в скрипт-файле и файле-функции
Приятного времени суток господа. Есть маленький вопрос, даже недоумение. Вот оно: Если я...

Создание баз данных c использованием CASE средств
Всем привет! У меня тема диплома &quot;Проектирование баз данных используя CASE средств&quot;. У меня будет...

Скрипт замены изображений
Вообщем написал скрипт своими силами Меняет картинки скрывая/показывая блоки с изображениями, но...

Скрипт замены текста
// Replace censored words in $text function censor_words_do($forum_censors, $text, $unicode) {...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru