Войти

Показать полную графическую версию : Замена строки в файле строкой из другого файла - нужна помощь


dixxia
09-04-2022, 03:59
У меня есть 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
У меня есть 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, причем, если таких слов несколько, выбрать это слово случайным образом.@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
megaloman, первый вариант правильный - огромное Спасибо!!! Наконец-то мои мучения заканчиваются!!! заработало!!!

dixxia
09-04-2022, 23:30
megaloman, сначала неправильно скопировал ваш скрипт, не работало, проверил еще раз, все работает!!! в личку отправил вам сообщение.

megaloman
09-04-2022, 23:59
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
megaloman, проверил на файле, почему то минут 5 заняла эта операция, файл 100kb, а я такие bat-ы с разными значениями на один файл буду запускать штук 10 последовательно. Почти час. Печально очень. В HexEdit за пару минут меняю. Есть ли возможность убыстрить, может другими путями, может PowerShell быстрее будет? Во вложении конкретный файл, именно с такими мне нужно работать.

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

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

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

dixxia
10-04-2022, 02:08
В 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
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
megaloman, это моя ошибка, что сразу не уточнил, что меняю в бинарном файле. Я не в курсе был, что "Для обработки текста CMD подходит плохо", теперь буду знать. Спасибо!




© OSzone.net 2001-2012