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

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

Stolc 17-06-2019 05:04 2875823

Скрипт для замены текста в файлах
 
Ищу решение - как лучше реализовать замену определенного текста в текстовом файле?
Файлы примерно по 5мб, разных пар текста для замены будет порядка 100 штук. То есть в каждом файле организовывается поиск примерно 100 различных тестовых фраз и , в случае их наличия, эти фразы заменяются на определенных другие текстовые фразы.
Реально ли данную задачу реализовать через командную строку? Какие варианты предложите?

megaloman 17-06-2019 12:22 2875858

Цитата:

Цитата Stolc
Файлы... »

Как понимать? Надо обрабатывать по одному файлу или сразу кучу? Они в какой-то указанной папке и имеют определённую маску или расширение, или надо иметь список этих файлов?
Цитата:

Реально ли данную задачу реализовать через командную строку? Какие варианты предложите?
ХЗ, дайте хотя бы один файл для примера и пару пар фраз для замены. ИМХО, скорее всего оптимум - vbs или powershell

Stolc 17-06-2019 12:49 2875861

Вложений: 1
Будет папка IN, в эту папку попадают файлы для обработки. После обработки файлы попадают в папку OUT.

Фразы для замены:
voronez=Воронеж
tver=Тверь
rostov=Ростов
sochi=Сочи

mwz 17-06-2019 13:23 2875870

Цитата:

Цитата Stolc
Фразы для замены: »

"Слово целиком", т.е. пробелы вокруг этих слов есть (или оно начальное, или конечное, или ограничено символами — т.е. именно так, как в примере)? А то ведь могут быть заменены соответствующие последовательности букв в других словах...

Stolc 17-06-2019 13:42 2875871

Именно слова целиком и только. Без пробелов и т.п.

megaloman 17-06-2019 15:02 2875875

Цитата:

Цитата Stolc
Именно слова целиком и только. »

Код:

@Echo Off
cls
        SetLocal EnableExtensions,EnableDelayedExpansion
        CHCP 1251 >nul

        Set  "BoxIn=Z:\Box_In"
        Set "BoxOut=Z:\Box_Out"
        Set "BoxArc=Z:\Box_Arc"

        Set "Mask=incoming*.txt"

        2>nul Md "%BoxOut%"
        2>nul Md "%BoxArc%"

        Call :Replacement

        FOR %%f IN ("%BoxIn%\%Mask%") DO (
                Echo "%%f"
                >"%BoxOut%\%%~nxf" (FOR /F "usebackq delims=" %%s IN ("%%f") DO (
                        Set "ss=%%s"
                        FOR /F "usebackq tokens=1* delims==" %%i IN (`Set "@@"`) DO Set "ss=!ss:%%j!"
                        Echo !ss!
                ))
                Move /Y "%%f" "%BoxArc%\"
        )
        EndLocal
pause
Exit /B

:Replacement

Set "@@001=voronez=Воронеж"
Set "@@002=tver=Тверь"
Set "@@003=rostov=Ростов"
Set "@@004=sochi=Сочи"

Exit /B

Не совсем понял постановку:
Цитата:

Цитата В Вашем файле
data=20.05.2018;from=tver;to=voronezh;quality=50;nds=15;

Цитата:

Цитата Если делать замену как указано
data=20.05.2018;from=Тверь;to=Воронежh;quality=50;nds=15;

Смущает буква h в voronezh -> Воронежh. Естественно, если пара для замены не указана, я не виноват.
Обработанные файлы перемещаю в архив.

Если файл надо получить в кодировке 1251, то и батник сохранить в этой кодировке, если в 866 - сохраните батник в 866 кодировке и убейте строку
CHCP 1251 >nul

Stolc 17-06-2019 15:36 2875881

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

Elven 17-06-2019 15:53 2875886

Stolc, можно попробовать другой скрипт. благо на форуме есть поиск

mwz 17-06-2019 16:08 2875891

Цитата:

Цитата megaloman
необходимость буквы h »

Думаю что ошибка в примере фраз для замены: ведь на аглицкий буква Ж транслитерируется не как Z, а как ZH.
Это я вынужденно усвоил с первых классов: смотрим мою подпись под сообщением. :)

Stolc 17-06-2019 16:34 2875901

Цитата:

Цитата megaloman
Stolc, Объясните мне необходимость буквы h, она в самом деле присутствует или это описка? Можно попробовать ускорить сие творение »

это описка

megaloman 17-06-2019 16:59 2875907

Попробуйте. Это решение именно для этой структуры Вашего файла
Код:

@Echo Off
cls
        SetLocal EnableExtensions,EnableDelayedExpansion
        CHCP 1251 >nul

        Set  "BoxIn=Z:\Box_In"
        Set "BoxOut=Z:\Box_Out"
        Set "BoxArc=Z:\Box_Arc"

        Set "Mask=incoming*.txt"

        2>nul Md "%BoxOut%"
        2>nul Md "%BoxArc%"

        Call :Replacement

        FOR %%f IN ("%BoxIn%\%Mask%") DO (
                Echo ========= "%%f"
                >"%BoxOut%\%%~nxf" (FOR /F "usebackq tokens=1,2,3,4,5,6,7,8,9,10 delims=;=" %%i IN ("%%f") DO (
                        Set "ssl=%%l"
                        Set "ssn=%%n"

                        Call :Substitute "ssl" "%%%%l%%"
                        Call :Substitute "ssn" "%%%%n%%"
                        Echo %%i=%%j;%%k=!ssl!;%%m=!ssn!;%%o=%%p;%%q=%%r;
                ))
                Move /Y "%%f" "%BoxArc%\"
        )
        EndLocal
pause
Exit /B

:Substitute
        If Not "%~2"=="" Set "%~1=%~2"
Exit /B

:Replacement

Set "voronez=Воронеж"
Set "tver=Тверь"
Set "rostov=Ростов"
Set "sochi=Сочи"

Exit /B


Stolc 17-06-2019 17:10 2875910

Вау, скрипты все сложнее..как тибетская клинопись. )
Не работает скрипт - пишет "для продолжения нажмите кнопку" и закрывается

megaloman 17-06-2019 17:17 2875913

Цитата:

Цитата Stolc
Не работает скрипт - пишет "для продолжения нажмите кнопку" и закрывается »

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

Stolc 17-06-2019 17:21 2875916

Да, пары переделал. В InBox файлы есть. Кодировка 1251. В OutBox не попадают файлы.

megaloman 17-06-2019 17:23 2875917

Цитата:

Цитата megaloman
А файлы отображаются при работе скрипта? »

Переименуйте ваш батник в txt-файл, предоставьте, и неплохо бы заархивировать реальный файл и приложить к сообщению, или фрагмент файла. Структура файла именно такая, или там еще какие-то заголовки присутствуют?

Stolc 17-06-2019 17:31 2875922

Беру паузу до завтра. Попробую разобраться позже. Спасибо за помощь!

Stolc 18-06-2019 12:27 2876010

В общем, попробовал через vbs-скрипт сделать замену в файлах. Все работает на ура.

Создал файл replace.vbs

PHP код:

Const ForReading 1    
Const ForWriting 2
strFileName 
Wscript.Arguments(0)
Set objFSO CreateObject("Scripting.FileSystemObject")
Set objFile objFSO.OpenTextFile(strFileNameForReading)
strText objFile.ReadAll
objFile
.Close

strText 
Replace(strText"voronez" "Воронеж")
strText Replace(strText"tver" "Тверь")
strText Replace(strText"sochi" "Сочи")

Set objFile objFSO.OpenTextFile(strFileNameForWriting)
objFile.Write strText  'WriteLine adds extra CR/LF
objFile.Close 

и через bat-файл запускаю его, указав в качестве параметра имя файла.

megaloman 18-06-2019 16:12 2876028

Цитата:

Цитата Stolc
Будет папка IN, в эту папку попадают файлы для обработки. После обработки файлы попадают в папку OUT.»

Ваш скрипт это не делает.
Вот вариант. Обрабатываются все файлы в инбоксе, обработанные идут в аутбокс, исходный перемещается в архив.
Это чистый vbs, CMD не задействован

Код:

BoxIn = "Z:\Box_In"
BoxOut = "Z:\Box_Out"
BoxArc = "Z:\Box_Arc"

RegExp = "incoming.*\.txt"

Mre = Array("voronez", "Воронеж", _
            "tver", "Тверь", _
            "rostov", "Ростов", _
            "sochi", "Сочи", _
            "moskva", "Москва", _
            "orel", "Орел")

Set Mask = CreateObject("VBScript.RegExp")
Mask.Pattern = RegExp
Mask.IgnoreCase = True
Mask.Global = True
           
j = 0
With CreateObject("Scripting.FileSystemObject")
    Set Fold = .GetFolder(BoxIn)
    Set Files = Fold.Files

    For Each iFile In Files      ' Цикл по файлам в папке (как вариант решения)
        If Mask.Test(iFile.Name) Then
            Set Fin = .OpenTextFile(iFile, 1, False)
            Text = Fin.ReadAll
            Fin.Close
           
            For i = LBound(Mre) To UBound(Mre) Step 2
                Text = Replace(Text, Mre(i), Mre(i + 1))
            Next
           
            Set Fout = .OpenTextFile(BoxOut + "\" + iFile.Name, 2, True)
            Fout.Write Text
            Fout.Close
           
            If .FileExists(BoxArc + "\" + iFile.Name) Then .DeleteFile BoxArc + "\" + iFile.Name, True
            .MoveFile iFile, BoxArc + "\"
            j = j + 1
        End If
    Next
End With
MsgBox "Обработано " + CStr(j) + " файлов"

Мой второй CMD работает на порядок быстрее, чем первый, однако vbs работает мигом.


Время: 11:34.

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