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

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

loficous 08-08-2018 08:01 2825402

Помогите написать батник для замещения-изменения содержимого txt файлов
 
Привет!
Я не умею писать батники, поэтому прошу вас помочь.
Нужен батник который будет все файлы 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 2825405

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

Цитата:

Цитата loficous
Например:
в папке лежать 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 2825549

Вложений: 1
Цитата:

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

прикладываю файлы.
они могут быть разного названия

Iska 09-08-2018 08:13 2825555

loficous, не вижу в примерах файлов ни "|104|", ни '00000004|".

loficous 09-08-2018 11:20 2825583

можно и без них. мне нужен хотябы пример, может дальше я сам допру.
"Set find=APLT"
"Set replace=1201"
это понятно. но как сделать чтобы он обрабатывал все файлы?
Цитата:

Цитата Iska
не вижу в примерах файлов ни "|104|", ни '00000004|". »


Darkar25 10-08-2018 08:09 2825730

я помню делал батник который перечитывает весь файл и заменяет в нём некоторые значения...при этом содержимое самого файла уходит в другой файл...это должно натолкнуть вас на какую-нибудь мысль...
код ниже.
Код
Код:

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 2825756

Цитата:

Цитата loficous
но как сделать чтобы он обрабатывал все файлы? »

Например, так (на 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 2825764

Спасибо вам большое, очень выручили.
только объясните пожалуйста как указать путь точный?
Цитата:

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

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

Цитата Darkar25
я помню делал батник который перечитывает весь файл и заменяет в нём некоторые значения...при этом содержимое самого файла уходит в другой файл...это должно натолкнуть вас на какую-нибудь мысль...
код ниже. »


Iska 10-08-2018 11:32 2825768

Цитата:

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

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

Darkar25 10-08-2018 11:46 2825772

Цитата:

Цитата loficous
только объясните пожалуйста как указать путь точный? »

вместо input.txt поставьте путь\до\файла\filename.txt...

Цитата:

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

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

loficous 10-08-2018 11:48 2825775

Я просто затупил при ответе.
Где в коде изменить чтобы указать путь к папке, не перетаскивая ее?
Цитата:

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


Iska 10-08-2018 11:57 2825777

Цитата:

Цитата loficous
Где в коде изменить чтобы указать путь к папке, не перетаскивая ее? »

Вообще-то, в коде — нигде.

Создайте пакетный файл, в котором напишите:
Код:

@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 2825799

Благодарю Вас за помощь.
Цитата:

Цитата Iska
Например, скрипт именуется Мой скрипт.vbs и находится по пути C:\Мои проекты\0180, обработать нужно каталог C:\Мои проекты\0180\0005. Тогда вторая строка будет выглядеть как: »


megaloman 10-08-2018 18:05 2825844

Вот батник с привлечением js
Код:

@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 2826155

Цитата:

Цитата megaloman
В батнике в For для каждого файла вызывается js. При этом в вызове необходимо указать пары для замены
"\|заменяемое\|" "|замена|"
Количество пар произвольно
Я принципиально хотел сохранить символы | при поиске и замене, из опасения ложного срабатывания. Но, каюсь, не сумел написать регулярное выражение, если указывать в виде
"|заменяемое|" "|замена|", поэтому приходится писать "\|заменяемое\|"
Путь к файлам укажите свой.
Надеюсь, найдутся люди и натыкают меня носом, как это сделать. »

Спасибо вам за ваши старания! Очень впечатлён отзывчивостью пользователей данного форума, если еще столкнусь с такими ситуациями обязательно обращусь.

loficous 31-01-2019 13:01 2855555

Цитата:

Цитата Iska
Вообще-то, в коде — нигде.
Создайте пакетный файл, в котором напишите:
Код:
@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 2855611

Цитата:

Цитата loficous
командная строка мелькает с надписью "ошибка ввода". »

Чтобы она не мелькала — сначала откройте её, а затем исполняйте в ней пакетный файл.

loficous 01-02-2019 06:12 2855708

Цитата:

Цитата Iska
Чтобы она не мелькала — сначала откройте её, а затем исполняйте в ней пакетный файл. »

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

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

Iska 01-02-2019 06:50 2855711

Цитата:

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

Конечно, можно. Просто сохраняйте пакетный файл в кодировке OEM/866. Стандартный Блокнот для этого не годится.

loficous 01-02-2019 11:22 2855723

Цитата:

Цитата Iska
Конечно, можно. Просто сохраняйте пакетный файл в кодировке OEM/866. Стандартный Блокнот для этого не годится. »

сейчас такая нелепая ситуация. не могу вспомнить как прописать путь так, чтобы он считывал из этой же папки (любой в какую его положишь)

Iska 01-02-2019 12:30 2855733

Цитата:

Цитата loficous
как прописать путь так, чтобы он считывал из этой же папки »

Предварите имя файла расширением переменной «%0»:
Код:

"%~dp0Имя файла.ext"


Время: 03:26.

Время: 03:26.
© OSzone.net 2001-