Войти

Показать полную графическую версию : [решено] Помогите написать батник для замещения-изменения содержимого txt файлов


Страниц : [1] 2

loficous
08-08-2018, 08:01
Привет!
Я не умею писать батники, поэтому прошу вас помочь.
Нужен батник который будет все файлы txt считывать, и изменять в них значения.
Например:
в папке лежать 4 файла с названиями типа "Pays_000000003_2018_08_62018_08_6.txt"
содержание в них такого типа:

Date_id|Branch_id|Pay_type|Account_id|Serv_id|Serv_name|Sum_pay|Last_count
06/08/2018|APLT|0|000077183|5|Холодная вода и кан-ция|2*441,00||

Нужно чтобы батник сам заменял значения "APLT" на "1201";"awnb" на "2527"; "ibhb"на"2526"; "kasp" на "4000"; "kpst" на "4001";"|104|" на "|5|"; '00000004|" на "|5|", и так во всех файлах находящихся в папке.

Iska
08-08-2018, 08:31
loficous, пакетные файлы вообще очень хреново подходят для задач замены части содержимого файлов. Или WSH, или PoSH.

Например:
в папке лежать 4 файла с названиями типа "Pays_000000003_2018_08_62018_08_6.txt"
содержание в них такого типа:
Date_id|Branch_id|Pay_type|Account_id|Serv_id|Serv_name|Sum_pay|Last_count
06/08/2018|APLT|0|000077183|5|Холодная вода и кан-ция|2*441,00|| »
Упакуйте эти четыре файла в архив, каковой приложите к сообщению.

loficous
09-08-2018, 06:16
пакетные файлы вообще очень хреново подходят для задач замены части содержимого файлов. Или WSH, или PoSH. »
прикладываю файлы.
они могут быть разного названия

Iska
09-08-2018, 08:13
loficous, не вижу в примерах файлов ни "|104|", ни '00000004|".

loficous
09-08-2018, 11:20
можно и без них. мне нужен хотябы пример, может дальше я сам допру.
"Set find=APLT"
"Set replace=1201"
это понятно. но как сделать чтобы он обрабатывал все файлы?
не вижу в примерах файлов ни "|104|", ни '00000004|". »

Darkar25
10-08-2018, 08:09
я помню делал батник который перечитывает весь файл и заменяет в нём некоторые значения...при этом содержимое самого файла уходит в другой файл...это должно натолкнуть вас на какую-нибудь мысль...
код ниже.
set /a NUM=0
Set Lines=0
Set "file=input.txt"
Set "out=out.txt"
set NoTot=0
set NoFil=
for %%a in (%file%) do call :ChkFile %%a
if %NoTot% == 0 goto start
echo [ %NoFil% ] FILES NOT EXISTS!"
goto eos
:start
For /F "usebackq" %%L In ("%file%") Do (Set /A Lines+=1)
set /a c=0
echo File Start\n >%out%
:loop
set /a c=0
set /a NUM+=1
for /f "UseBackQ Delims=" %%A IN ("%file%") do (
set /a c+=1
if !c!==!NUM! set "line=%%A"
)
//здесь производим замену значений
set "line=!line:zamenyaem-eto=zamenyaem-na-eto!"
if "!NUM!"=="!Lines!" (goto finish)
echo !line! >>%out%
cls
echo !NUM! of !Lines!.
goto loop
:finish
cls
echo Finished!your text has saved in %out%
:eos
pause
:ChkFile
if exist %1 goto :eof
set NoFil=%NoFil% %1
set /a NoTot=%NoTot%+1
goto :eof
endlocal
правда есть один минус....если строки длинные и их много процесс может затянуться на час ато и больше(я тестировал на строках длинной чуть больше 50-ти символов и количеством строк 8700.время работы составило 1 час)

Iska
10-08-2018, 10:57
но как сделать чтобы он обрабатывал все файлы? »
Например, так (на WSH):
Option Explicit

Dim strSourceFolder

Dim objFSO
Dim objFile

Dim objRegExp
Dim objDictionary

Dim strContent

Dim strKey


If WScript.Arguments.Count = 1 Then
strSourceFolder = WScript.Arguments.Item(0)

Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

If objFSO.FolderExists(strSourceFolder) Then
Set objRegExp = WScript.CreateObject("VBScript.RegExp")

With objRegExp
.Pattern = "Pays_[\d_]+\.txt"
.IgnoreCase = True
End With

Set objDictionary = WScript.CreateObject("Scripting.Dictionary")

With objDictionary
.Add "APLT" , "1201"
.Add "awnb" , "2527"
.Add "ibhb" , "2526"
.Add "kasp" , "4000"
.Add "kpst" , "4001"
.Add "|104|" , "|5|"
.Add "|00000004|", "|5|"
End With

For Each objFile In objFSO.GetFolder(strSourceFolder).Files
If objRegExp.Test(objFile.Name) Then
WScript.Echo objFile.Path

With objFSO.OpenTextFile(objFile.Path)
strContent = .ReadAll()
.Close
End With

For Each strKey In objDictionary.Keys
strContent = Replace(strContent, strKey, objDictionary.Item(strKey), 1, -1, vbTextCompare)
Next

With objFSO.CreateTextFile(objFile.Path, True)
.Write strContent
.Close
End With
Else
' Nothing to do
End If
Next

objDictionary.RemoveAll
Set objDictionary = Nothing
Set objRegExp = Nothing
Else
WScript.Echo "Can't find source folder [" & strSourceFolder & "]."
WScript.Quit 2
End If

Set objFSO = Nothing
Else
WScript.Echo "Usage: cscript.exe //nologo """ & WScript.ScriptName & """ <Source folder>"
WScript.Quit 1
End If

WScript.Quit 0

Целевая папка указывается параметром скрипта (также можно просто перетащить папку на скрипт в Проводнике). Имена файлов ожидаются в виде «Pays_<цифры и подчёркивания>.txt».

loficous
10-08-2018, 11:21
Спасибо вам большое, очень выручили.
только объясните пожалуйста как указать путь точный?Например, так (на WSH):
Скрытый текст
Целевая папка указывается параметром скрипта (также можно просто перетащить папку на скрипт в Проводнике). Имена файлов ожидаются в виде «Pays_<цифры и подчёркивания>.txt». »
извините мне нужен батник который будет не один файл считывать, а несколько. в конкретной папке
я помню делал батник который перечитывает весь файл и заменяет в нём некоторые значения...при этом содержимое самого файла уходит в другой файл...это должно натолкнуть вас на какую-нибудь мысль...
код ниже. »

Iska
10-08-2018, 11:32
извините мне нужен батник который будет не один файл считывать, а несколько. в конкретной папке. »
Так и сделано. «Конкретная папка» указывается параметром при вызове скрипта. Можете просто перетаскивать потребную папку прямо на скрипт (или на ярлык на скрипт) в Проводнике. В этой папке будут обработаны все файлы вида «Pays_<цифры и подчёркивания>.txt».

Darkar25
10-08-2018, 11:46
только объясните пожалуйста как указать путь точный? »
вместо input.txt поставьте путь\до\файла\filename.txt...

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

loficous
10-08-2018, 11:48
Я просто затупил при ответе.
Где в коде изменить чтобы указать путь к папке, не перетаскивая ее?
Так и сделано. «Конкретная папка» указывается параметром при вызове скрипта. Можете просто перетаскивать потребную папку прямо на скрипт (или на ярлык на скрипт) в Проводнике. В этой папке будут обработаны все файлы вида «Pays_<цифры и подчёркивания>.txt». »

Iska
10-08-2018, 11:57
Где в коде изменить чтобы указать путь к папке, не перетаскивая ее? »
Вообще-то, в коде — нигде.

Создайте пакетный файл, в котором напишите:
@echo off
cscript.exe //nologo "Путь к скрипту" "Путь к папке"
Например, скрипт именуется Мой скрипт.vbs и находится по пути C:\Мои проекты\0180, обработать нужно каталог C:\Мои проекты\0180\0005. Тогда вторая строка будет выглядеть как:
cscript.exe //nologo "C:\Мои проекты\0180\Мой скрипт.vbs" "C:\Мои проекты\0180\0005"

loficous
10-08-2018, 13:32
Благодарю Вас за помощь.Например, скрипт именуется Мой скрипт.vbs и находится по пути C:\Мои проекты\0180, обработать нужно каталог C:\Мои проекты\0180\0005. Тогда вторая строка будет выглядеть как: »

megaloman
10-08-2018, 18:05
@set @E=1; /*
@Echo Off
cls

Set "FileIn=Z:\Soft_In\Pays_*.txt"
rem 1 2 3 4 5 6 7
FOR %%f IN ("%FileIn%") DO Call Cscript //NoLogo /E:jscript "%~dpnx0" "%%f" "\|APLT\|" "|1201|" "\|awnb\|" "|2527|" "\|ibhb\|" "|2526|" "\|kasp\|" "|4000|" "\|kpst\|" "|4001|" "\|104\|" "|5|" "\|00000004\|" "|5|"

pause
GoTo :Eof

*/
var oArg = WScript.Arguments;
var nArg = oArg.Count();
var nRep = Math.floor(nArg/2);

if (nArg <= 3 || nRep == nArg/2) {
WScript.Echo("Error! Invalid number of arguments!");
WScript.Quit(240);
}
var FText=oArg(0);

var FSO=WScript.CreateObject("Scripting.FileSystemObject");

var InFile;
try {InFile = FSO.OpenTextFile(FText,1);}
catch (e) {
if (e !=0 ) {
WScript.Echo("Error! " + FText + " " + e.description);
WScript.Quit(240);
}
}
var TextAll = InFile.ReadAll();
InFile.Close();

var ss,RegRep;

for (var i = 1; i < nArg; i+=2) {
// WScript.Echo(oArg(i) + " " + oArg(i+1));
TextAll=TextAll.replace(new RegExp(oArg(i),"ig"),oArg(i+1));
}

InFile = FSO.OpenTextFile(FText,2);
InFile.Write(TextAll);
InFile.Close();В батнике в For для каждого файла вызывается js. При этом в вызове необходимо указать пары для замены
"\|заменяемое\|" "|замена|"
Количество пар произвольно
Я принципиально хотел сохранить символы | при поиске и замене, из опасения ложного срабатывания. Но, каюсь, не сумел написать регулярное выражение, если указывать в виде
"|заменяемое|" "|замена|", поэтому приходится писать "\|заменяемое\|"
Путь к файлам укажите свой.
Надеюсь, найдутся люди и натыкают меня носом, как это сделать. :(

loficous
13-08-2018, 11:08
В батнике в For для каждого файла вызывается js. При этом в вызове необходимо указать пары для замены
"\|заменяемое\|" "|замена|"
Количество пар произвольно
Я принципиально хотел сохранить символы | при поиске и замене, из опасения ложного срабатывания. Но, каюсь, не сумел написать регулярное выражение, если указывать в виде
"|заменяемое|" "|замена|", поэтому приходится писать "\|заменяемое\|"
Путь к файлам укажите свой.
Надеюсь, найдутся люди и натыкают меня носом, как это сделать. »Спасибо вам за ваши старания! Очень впечатлён отзывчивостью пользователей данного форума, если еще столкнусь с такими ситуациями обязательно обращусь.

loficous
31-01-2019, 13:01
Вообще-то, в коде — нигде.
Создайте пакетный файл, в котором напишите:
Код:
@echo off
cscript.exe //nologo "Путь к скрипту" "Путь к папке"
Например, скрипт именуется Мой скрипт.vbs и находится по пути C:\Мои проекты\0180, обработать нужно каталог C:\Мои проекты\0180\0005. Тогда вторая строка будет выглядеть как:
Код:
cscript.exe //nologo "C:\Мои проекты\0180\Мой скрипт.vbs" "C:\Мои проекты\0180\0005" »
Здравствуйте!! только увидел ваше сообщение, и решил попробовать. попытка не увенчалась успехом, командная строка мелькает с надписью "ошибка ввода".

Iska
31-01-2019, 18:54
командная строка мелькает с надписью "ошибка ввода". »
Чтобы она не мелькала — сначала откройте её, а затем исполняйте в ней пакетный файл.

loficous
01-02-2019, 06:12
Чтобы она не мелькала — сначала откройте её, а затем исполняйте в ней пакетный файл. »
до меня дошло почему она так не запускалась.
дело в том, что в прописываемом пути не должно быть кирилицы (названия папок и самого скрипта).
как только я сделал так как вы сказали,сразу увидел что пишется в командной строке и выявил проблему.

вопрос можно ли какнибудь сделать так чтобы он принимал кирилицу, или нет?

Iska
01-02-2019, 06:50
опрос можно ли какнибудь сделать так чтобы он принимал кирилицу, или нет? »
Конечно, можно. Просто сохраняйте пакетный файл в кодировке OEM/866. Стандартный Блокнот для этого не годится.

loficous
01-02-2019, 11:22
Конечно, можно. Просто сохраняйте пакетный файл в кодировке OEM/866. Стандартный Блокнот для этого не годится. »
сейчас такая нелепая ситуация. не могу вспомнить как прописать путь так, чтобы он считывал из этой же папки (любой в какую его положишь)




© OSzone.net 2001-2012