Компьютерный форум 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=351013)

dixxia 09-04-2022 03:59 2982937

Замена строки в файле строкой из другого файла - нужна помощь
 
У меня есть bat
bat
@echo
setlocal enableextensions enabledelayedexpansion

set sFile=1.txt
set sTempFile=TempFile.tmp

for /f "usebackq" %%i in (`type "%sFile%" ^| find.exe /c /v ""`) do set sLines=%%i

set /a iLine = sLines * %Random% / 32768

more +%iLine% "%sFile%">"%sTempFile%"
<"%sTempFile%" set /p sVar=>nul

echo %sVar% >2.txt

endlocal
exit /b 0


Рандомно вытаскивает из файла 1.txt строку и копирует ее в новый файл 2.txt

Помогите добавить в этот же bat команду, которая берет содержимое файла 2.txt (одно текст. слово длиной 5-12 символов на латинице) и заменяет им строку Sample123 в файле out.dat

megaloman 09-04-2022 19:02 2982987

Цитата:

Цитата dixxia
У меня есть bat »

Не очень информативно. Можно понять так:
В 1.txt каждая строка - это слово длиной 5-12 символов на латинице
Рандомно выбирается строка из 1.txt (это слово 5-12 символов) и записывается в файл 2.txt
В файле out.dat слово Sample123 заменяется словом записанным в 2.txt
Для такой постановки (Ваш кусок переписал)
Код:

@Echo Off
cls
        Set "File1=Z:\Box_In\1.txt"
        Set "FileOut=Z:\Box_In\2.txt"
        Set "FileRep=Z:\Box_In\out.dat"
        Set "Rep=Sample123"

        Set /A N=0
        For /f "usebackq Skip=2 tokens=1* delims=[]" %%i In (`2^>nul Find.exe /V /N "" "%File1%"`) Do Call Set R=%%Random%% &If Not "%%j"=="" Set /A N=%%i

        Set /A R=%N%*%Random%/32768
        For /f "usebackq delims=" %%i In (`2^>nul More +%R% "%File1%"`) Do (
                Set "RR=%%i"
                >"%FileOut%" (Echo %%i)
                GoTo :Cont
        )
        :Cont
        FOR /F "usebackq skip=2 tokens=1* delims=[]" %%i In (`2^>nul Find /V /N "" "%FileRep%"`) DO (
                Set Str=.%%j
                Set /A Num=100000000+%%i
                Call Set "@3@%%Num%%=%%Str:%Rep%=%RR%%%"
        )

        >"%FileRep%" (FOR /F "usebackq tokens=2 delims==" %%i In (`2^>nul Set "@3@"`) DO Echo%%i)
Pause
Exit /B

Если всё сложнее,
- в 1.txt строки с произвольными словами
- в 2.txt надо записать одну из строк из 1.txt, в которой обязательно есть хотя бы одно слово длиной 5-12 символов на латинице
- в файле out.dat слово Sample123 заменяется словом записанным в строке 2.txt, причем, если таких слов несколько, выбрать это слово случайным образом.
При этом код в CMD получается более громоздким
Код:

@echo off
cls
        Set "File1=Z:\Box_In\1.txt"
        Set "FileOut=Z:\Box_In\2.txt"
        Set "FileRep=Z:\Box_In\out.dat"
        Set "Rep=Sample123"

        Set "Reg1=/C:" [A-Z][A-Z][A-Z][A-Z][A-Z][A-Z]* ""
        Set "Reg2=/C:"[A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z][A-Z]""
        Set "Reg3=/C:"^[A-Z][A-Z][A-Z][A-Z][A-Z][A-Z]*$""

        If Not Exist "%File1%" (Echo File not found "%File1%" &Pause &Exit /B 2)
        >"%FileOut%" cd. || (Echo "%FileOut%" &Pause &Exit /B 2)
        If Not Exist "%FileRep%" (Echo File not found "%FileRep%" &Pause &Exit /B 2)

        Set "N=0"
        FOR /F "usebackq delims=" %%i In (`More "%File1%"`) DO (
                (Echo  %%i )|>nul FINDSTR /I /R %Reg1% && (
                        Set /A N+=1
                        Call Set "@1@%%N%%=%%i"
                )
        )
        If %N%==0 (Echo File not correct "%File1%"! &Pause &Exit /B 2)

rem        Set "@1@"
        Set R=%Random%
       
        Set /A K=0
        :Begin
                Set /A R=1+%N%*%Random%/32768
                Call Set "R=%%@1@%R%%%"

                Set /A M=0
                For %%i In (%R%) Do (
                        Echo %%i|FINDSTR /V /I /R %Reg2%|>nul FINDSTR /I /R %Reg3% &&(
                                Set /A M+=1
                                Call Set "@2@%%M%%=%%i"
                        )
                )

                Set /A K+=1
                If %M%==0 (If %K% GTR 20 (Echo File not correct!! "%File1%"  &Pause &Exit /B 2))
                If %M%==0 GoTo :Begin
               
rem                Set "@2@"
                Set /A RR=1+%M%*%Random%/32768
                Call Set "RR=%%@2@%RR%%%"
                >"%FileOut%" (Echo %R%)
rem                Echo RR=%RR%

                FOR /F "usebackq skip=2 tokens=1* delims=[]" %%i In (`2^>nul Find /V /N "" "%FileRep%"`) DO (
                        Set Str=.%%j
                        Set /A Num=100000000+%%i
                        Call Set "@3@%%Num%%=%%Str:%Rep%=%RR%%%"
                )

                >"%FileRep%" (FOR /F "usebackq tokens=2 delims==" %%i In (`2^>nul Set "@3@"`) DO Echo%%i)
Pause
Exit /B


dixxia 09-04-2022 21:26 2983002

megaloman, первый вариант правильный - огромное Спасибо!!! Наконец-то мои мучения заканчиваются!!! заработало!!!

dixxia 09-04-2022 23:30 2983008

megaloman, сначала неправильно скопировал ваш скрипт, не работало, проверил еще раз, все работает!!! в личку отправил вам сообщение.

megaloman 09-04-2022 23:59 2983010

dixxia, Я еще оттестировал батник, убедился, что он работает. Но предполагается, что файлы текстовые. С бинарным файлом штатными утилитами вряд ли возможно. На всякий случай добавил в батник контроль наличия файлов.
Код:

@Echo Off
cls
        Set "File1=1.txt"
        Set "FileOut=2.txt"
        Set "FileRep=out.dat"
        Set "Rep=Samp123"

        If Not Exist "%File1%" (Echo File not found "%File1%" &Pause &Exit /B 2)
        >"%FileOut%" cd. || (Echo "%FileOut%" &Pause &Exit /B 2)
        If Not Exist "%FileRep%" (Echo File not found "%FileRep%" &Pause &Exit /B 2)

        Set /A N=0
        For /f "usebackq Skip=2 tokens=1* delims=[]" %%i In (`2^>nul Find.exe /V /N "" "%File1%"`) Do Call Set R=%%Random%% &If Not "%%j"=="" Set /A N=%%i

        Set /A R=%N%*%Random%/32768
        For /f "usebackq delims=" %%i In (`2^>nul More +%R% "%File1%"`) Do (
                Set "RR=%%i"
                >"%FileOut%" (Echo %%i)
                GoTo :Cont
        )
        :Cont

        FOR /F "usebackq skip=2 tokens=1* delims=[]" %%i In (`2^>nul Find /V /N "" "%FileRep%"`) DO (
                Set Str=.%%j
                Set /A Num=100000000+%%i
                Call Set "@3@%%Num%%=%%Str:%Rep%=%RR%%%"
        )

        Set /A Num-=100000000
        Echo This file contains %Num% lines: "%FileRep%"

        >"%FileRep%" (FOR /F "usebackq tokens=2 delims==" %%i In (`2^>nul Set "@3@"`) DO Echo%%i)
Pause
Exit /B


dixxia 10-04-2022 00:34 2983018

megaloman, проверил на файле, почему то минут 5 заняла эта операция, файл 100kb, а я такие bat-ы с разными значениями на один файл буду запускать штук 10 последовательно. Почти час. Печально очень. В HexEdit за пару минут меняю. Есть ли возможность убыстрить, может другими путями, может PowerShell быстрее будет? Во вложении конкретный файл, именно с такими мне нужно работать.

out.ggu это то, что я собирался подставлять вместо out.dat (текст samp123 почти в самом начале, встречается тольк один раз)

1.txt - это текстовой список

не прикрепляет, наверно потому что недавно зарегистрировался на форуме

dixxia 10-04-2022 02:08 2983024

В sfk команда sfk replace -binary /3232323220536f6e/4444444444444444/ -force -dir out.dat меняет бинарные 32 32 32 32 20 53 6f 6e на 44 44 44 44 44 44 44 44 мгновенно, и текст так же. Копаюсь в документации, пытаюсь сделать аналог скрипта ув.megaloman, серого вещества не хватвет катастрофически....

megaloman 10-04-2022 14:32 2983035

dixxia, Вы задали вопрос в теме CMD, получили bat. Для обработки текста CMD подходит плохо. Вот для текстовых файлов vbs-скрипт исполняется мгновенно.
Код:

File1 = "Z:\Box_In\1.txt"
FileOut = "Z:\Box_In\2.txt"
FileRep = "Z:\Box_In\out.dat"
Rep = "Samp123"

Randomize
With CreateObject("Scripting.FileSystemObject")

    On Error Resume Next
   
    Set fIn = .OpenTextFile(File1, 1, False)
    If Err.Number <> 0 Then
        MsgBox File1 + vbCr + vbCr + Err.Description, vbCritical
        WScript.Quit 2
    End If
   
    MasSpis = Split(fIn.ReadAll, vbCrLf)
    If Err.Number <> 0 Then
        MsgBox File1 + vbCr + vbCr + Err.Description, vbCritical
        WScript.Quit 2
    End If
    fIn.Close
     
    i1 = LBound(MasSpis)
    i2 = UBound(MasSpis)
    RepRnd = Trim(MasSpis(Int((i2 - i1 + 1) * Rnd + i1)))
    Erase MasSpis
    Set fIn = .OpenTextFile(FileOut, 2, True)
    If Err.Number <> 0 Then
        MsgBox FileOut + vbCr + vbCr + Err.Description, vbCritical
        WScript.Quit 2
    End If
    fIn.Write RepRnd
    fIn.Close
   
    Set fIn = .OpenTextFile(FileRep, 1, False)
    If Err.Number <> 0 Then
        MsgBox FileRep + vbCr + vbCr + Err.Description, vbCritical
        WScript.Quit 2
    End If
    OutRep = Replace(fIn.ReadAll, Rep, RepRnd)
    fIn.Close
   
    Set fIn = .OpenTextFile(FileRep, 2, True)
    If Err.Number <> 0 Then
        MsgBox FileRep + vbCr + vbCr + Err.Description, vbCritical
        WScript.Quit 2
    End If
    OutRep = Replace(fIn.ReadAll, Rep, RepRnd)
    fIn.Write OutRep
    fIn.Close
    On Error GoTo 0
End With

Возможно, PowerShell работает быстрее, и, возможно, обработает бинарные файлы.

dixxia 12-04-2022 01:37 2983113

megaloman, это моя ошибка, что сразу не уточнил, что меняю в бинарном файле. Я не в курсе был, что "Для обработки текста CMD подходит плохо", теперь буду знать. Спасибо!


Время: 11:46.

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