Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Изменение текста в ini файлах (http://forum.oszone.net/showthread.php?t=346509)

romfus 23-09-2020 14:45 2934720

Изменение текста в ini файлах
 
Добрый день. Имеются ini файлы, все они лежат в одном месте (Пусть будет D:\test).
Как можно с помощью скрипта изменить сразу несколько строк во всех ini файлах?
Нужно поменять PostMark=536871936 на PostMark=1024 и DocVersion=RTM0099 на DocVersion=RTM003-13-17

greg zakharov 23-09-2020 14:52 2934724

romfus, приведите пример ini.

romfus 23-09-2020 15:00 2934731

Текст ini:
Код:

[Main]
SndrFact=–Ђ”ЂЏЋ„„ ѓ€Ѓ„„ ѓ“ Њ‚„ ђ®ббЁЁ Ї® ‚®«Ј®Ја*¤бЄ®© ®Ў«
InnFact=3444012677
KppFact=344401001
Inn=3444268848
Kpp=344401001
DepCode=1118026
SndrTel=
SendCtg=2
SendDate=20200915
ListNum=78000
IndexFrom=400066
MailType=2
MailCtg=1
DirectCtg=1
PayType=2
PayTypeNot=2
TransType=1
PostMark=536871936
MailRank=8
NumContract=8.4.10-09-79
SMSNoticeS=

[Sender]
Sndr=ѓЋ‘“„Ђђ‘’‚…ЌЌЋ… ЉЂ‡…ЌЌЋ… “—ђ…†„…Ќ€… ‚Ћ‹ѓЋѓђЂ„‘ЉЋ‰ ЋЃ‹Ђ‘’€ "Ѓ…‡ЋЏЂ‘Ќ›‰ ђ…ѓ€ЋЌ"
AddressTypeSndr=1
NumAddressTypeSndr=
IndexSndr=400066
RegionSndr=‚®«Ј®Ја*¤бЄ*п
AreaSndr=
PlaceSndr=‚®«Ј®Ја*¤
LocationSndr=
StreetSndr=Ё¬. ‘Є®блॢ*
HouseSndr=2
LetterSndr=Le
SlashSndr=
CorpusSndr=
BuildingSndr=
HotelSndr=
RoomSndr=

[Summary]
MailCount=500
DeliveryRateSum=2700000
DeliveryRateVAT=540000
DeliveryRateTotal=3240000
ValueSum=0
ValueSumRateTotal=0
ValueSumRateVAT=0
NoticeRateTotal=0
NoticeRateVAT=0
SMSNoticeTotal=0
SMSNoticeVAT=0
TotalRate=3240000
TotalRateVAT=540000

[DocVersion]
DocVersion=RTM0099


greg zakharov 23-09-2020 15:07 2934736

Погодите трошки. Сейчас накидаю.

Код:

@echo off
 setlocal enabledelayedexpansion
  for /r D:\test %%i in (*.ini) do call:patch "%%i"
 endlocal
exit /b

:getlines
  for /f %%i in ('find /c /v "" ^< "%~1"') do set "#=%%i"
exit /b

:replace
  3<"%~1" (for /l %%i in (1,1,!#!) do (
    set /p s=<&3
    for /f "tokens=1,* delims==" %%i in ("!s!") do (
      if /i "%%i" equ "postmark" (
        echo:%%i=1024
      ) else if /i "%%i" equ "docversion" (
        echo:%%i=RTM003-13-17
      ) else if "!s:~0,1!" equ "[" (
        echo.
        echo:%%i
      ) else echo:%%i=%%j
    )
  ))>>"%tmp%\ini000.tmp"
  move "%tmp%\ini000.tmp" "%~1" >nul
exit /b

:patch
  call:getlines "%~1"
  call:replace  "%~1"
exit /b


romfus 23-09-2020 16:05 2934758

Что - то вот такое получается
Код:

[Main]

SndrFact

InnFact

KppFact

Inn

Kpp

DepCode

SndrTel

SendCtg

SendDate

ListNum

IndexFrom

MailType

MailCtg

DirectCtg

PayType

PayTypeNot

TransType
PostMark=1024

MailRank

NumContract

SMSNoticeS

[Sender]

Sndr

AddressTypeSndr

NumAddressTypeSndr

IndexSndr

RegionSndr

AreaSndr

PlaceSndr

LocationSndr

StreetSndr

HouseSndr

LetterSndr

SlashSndr

CorpusSndr

BuildingSndr

HotelSndr

RoomSndr

[Summary]

MailCount

DeliveryRateSum

DeliveryRateVAT

DeliveryRateTotal

ValueSum

ValueSumRateTotal

ValueSumRateVAT

NoticeRateTotal

NoticeRateVAT

SMSNoticeTotal

SMSNoticeVAT

TotalRate

TotalRateVAT

[DocVersion]
DocVersion=RTM0003-13-17

[Main]

SndrFact

InnFact

KppFact

Inn

Kpp

DepCode

SndrTel

SendCtg

SendDate

------Пропускаю много символов ------------------
[DocVersion]
DocVersion=RTM0003-13-17



Все значения которые нужно поменять поменялись а остальные исчезли, и все это скопировалось много раз

greg zakharov 23-09-2020 16:24 2934764

romfus, ещё раз прогнал пять тестов на сотне клонов предоставленного вами ini, но в итоге получаю корректные:
Код:

[Main]
SndrFact=ЦАФАПОДД ГИБДД ГУ МВД России по Волгоградской обл
InnFact=3444012677
KppFact=344401001
Inn=3444268848
Kpp=344401001
DepCode=1118026
SndrTel=
SendCtg=2
SendDate=20200915
ListNum=78000
IndexFrom=400066
MailType=2
MailCtg=1
DirectCtg=1
PayType=2
PayTypeNot=2
TransType=1
PostMark=1024
MailRank=8
NumContract=8.4.10-09-79
SMSNoticeS=
SMSNoticeS=

[Sender]
Sndr=ГОСУДАРСТВЕННОЕ КАЗЕННОЕ УЧРЕЖДЕНИЕ ВОЛГОГРАДСКОЙ ОБЛАСТИ "БЕЗОПАСНЫЙ РЕГИОН"
AddressTypeSndr=1
NumAddressTypeSndr=
IndexSndr=400066
RegionSndr=Волгоградская
AreaSndr=
PlaceSndr=Волгоград
LocationSndr=
StreetSndr=им. Скосырева
HouseSndr=2
LetterSndr=Le
SlashSndr=
CorpusSndr=
BuildingSndr=
HotelSndr=
RoomSndr=
RoomSndr=

[Summary]
MailCount=500
DeliveryRateSum=2700000
DeliveryRateVAT=540000
DeliveryRateTotal=3240000
ValueSum=0
ValueSumRateTotal=0
ValueSumRateVAT=0
NoticeRateTotal=0
NoticeRateVAT=0
SMSNoticeTotal=0
SMSNoticeVAT=0
TotalRate=3240000
TotalRateVAT=540000
TotalRateVAT=540000

[DocVersion]
DocVersion=RTM003-13-17

Скорее всего дело в кодировке.

romfus 23-09-2020 16:32 2934767

Нужно скинуть ini файл? Или как то можно кодировку прописать в скрипте?

greg zakharov 23-09-2020 16:37 2934770

У вас ini в какой кодировке?

romfus 23-09-2020 16:42 2934772

Ansi

greg zakharov 23-09-2020 17:05 2934774

Попробуйте "прогнать" сценарий на каком-нибудь одном файле, т.е. строчку for /r D:\test %%i in (*.ini) do call:patch "%%i" замените на call:patch D:\test\имя_существующего_файла.ini

romfus 23-09-2020 19:00 2934789

Цитата:

Цитата greg zakharov
call:patch D:\test\имя_существующего_файла.ini »

тоже самое

может к скрипту добавить шаг с перекодировкой?

greg zakharov 23-09-2020 21:13 2934801

Попробуйте.

romfus 23-09-2020 21:18 2934802

а как этот шаг добавить? chcp не помогает

DJ Mogarych 23-09-2020 22:06 2934807

Powershell
Код:

$path = 'c:\temp\file.ini'
$ini = gc "$path" -Encoding oem

$ini -replace 'PostMark=536871936','PostMark=1024' `
-replace 'DocVersion=RTM0099','DocVersion=RTM003-13-17' |
Set-Content "$path" -Encoding oem


Iska 23-09-2020 23:22 2934814

romfus, упакуйте Ваш ini-файл в архив, каковой приложите к сообщению.

romfus 24-09-2020 08:09 2934832

Вложений: 1
Секунду

romfus 24-09-2020 08:12 2934833

Вложений: 1
Прикрепил

DJ Mogarych 24-09-2020 12:24 2934849

Ну, мой скрипт корректно работает.

greg zakharov 24-09-2020 17:17 2934866

Цитата:

Цитата DJ Mogarych
Ну, мой скрипт корректно работает.

То же могу сказать и про своё решение. Отличие лишь в том, что в PowerShell проще с кодировками, а в cmd нужно танцевать с бубном (чего делать не хочется). Проще PowerShell будет разве что sed:
Код:

sed -i "/postmark/Is/^\(.*=\)\(.*\)/\11024/;/docversion/Is/^\(.*=rtm00\)\(.*\)/\13-13-17/Ig" input.ini
А ещё проще задача решается на Q:
Код:

q "replace ig '^[postm,docve]*=,', [1024, 'RTM003-13-17']" < inpit.ini
И это также будет работать.

romfus 25-09-2020 09:45 2934903

Проблема в том что с помощью вашего скрипта, внутри ini файла все задваивается. Как будто он не только изменяет эти значения а еще и объединяет файлы в один или просто копируется все много раз. Попробовал с 1 файлом все получилось. Попробовал с множеством файлов все задвоилось внутри ini

Попробуйте ini файл скопировать, чтобы было 2 файла и скриптом выполнить. Получится задвоение внутри ini. По одному делает. Когда несколько делает но задваивает

greg zakharov 25-09-2020 13:53 2934925

romfus, кому адресованы ваши слова?

romfus 26-09-2020 04:10 2934963

В любом из выше предложенных вариантов такое

Uragan66 26-09-2020 08:06 2934967

romfus, пробуйте мой вариант:

powershell
Код:

$path = 'J:\Download\'

ForEach ($file in (Get-ChildItem $path -Filter *.ini -File))
{
$fcontent = Get-Content $file -Encoding oem `
 | ForEach {$_.Replace('PostMark=536871936','PostMark=1024').Replace('DocVersion=RTM0099','DocVersion=RTM003-13-17')}
Set-Content $('new_'+$file.Name) -Value $fcontent
}

В переменной $path замените путь на свой

greg zakharov 26-09-2020 14:39 2934997

Цитата:

Цитата romfus
В любом из выше предложенных вариантов такое

Ой ли? Желаете доказательств, что вы лжец и провокатор?

megaloman 27-09-2020 11:13 2935030

romfus,
VBS-скрипт. Создйте файл в 1251 кодировке (если в пути кириллица-это важно) с расширением .vbs и выполните его
Код:

MyDir = "Z:\Box_Arc\Тра ля ля"
MyMask = "^.*\.ini$"

MyRep = Array( _
    "PostMark=536871936", _
    "PostMark=1024", _
    "DocVersion=RTM0099", _
    "DocVersion=RTM003-13-17" _
)

Set Reg = CreateObject("VBScript.RegExp")
Reg.IgnoreCase = True
Reg.Pattern = MyMask

With CreateObject("Scripting.FileSystemObject")
    Set Files = .GetFolder(MyDir).Files
   
    For Each File In Files
        Filename = File.Path
        If Reg.Test(Filename) Then
            Set fIn = .OpenTextFile(Filename, 1, False)
            InTxt = fIn.ReadAll
            fIn.Close
           
            L = False
            For i = LBound(MyRep) To UBound(MyRep) Step 2
                If InStr(InTxt, MyRep(i)) > 0 Then
                    L = True
                    InTxt = Replace(InTxt, MyRep(i), MyRep(i + 1))
                End If
            Next
            If L Then
                Set fIn = .CreateTextFile(Filename, True)
                fIn.Write InTxt
                fIn.Close
            End If
        End If
    Next
End With
MsgBox "Done"


romfus 28-09-2020 09:01 2935099

Работает. Спасибо!

AleksandrG 29-09-2020 23:04 2935235

Цитата:

Цитата romfus
с помощью скрипта изменить сразу несколько строк во всех ini файлах »

а с помощью скрипта это принципиально?
В AkelPad есть замена текста сразу во всех открытых файлах
Вероятно, есть и другие текстовые редакторы с такой возможностью


Время: 15:11.

Время: 15:11.
© OSzone.net 2001-