Показать полную графическую версию : Замена строки в файле строкой из другого файла - нужна помощь
У меня есть 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
megaloman, первый вариант правильный - огромное Спасибо!!! Наконец-то мои мучения заканчиваются!!! заработало!!!
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
megaloman, проверил на файле, почему то минут 5 заняла эта операция, файл 100kb, а я такие bat-ы с разными значениями на один файл буду запускать штук 10 последовательно. Почти час. Печально очень. В HexEdit за пару минут меняю. Есть ли возможность убыстрить, может другими путями, может PowerShell быстрее будет? Во вложении конкретный файл, именно с такими мне нужно работать.
out.ggu это то, что я собирался подставлять вместо out.dat (текст samp123 почти в самом начале, встречается тольк один раз)
1.txt - это текстовой список
не прикрепляет, наверно потому что недавно зарегистрировался на форуме
В 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 работает быстрее, и, возможно, обработает бинарные файлы.
megaloman, это моя ошибка, что сразу не уточнил, что меняю в бинарном файле. Я не в курсе был, что "Для обработки текста CMD подходит плохо", теперь буду знать. Спасибо!
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.