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

Дмитрий_Кульгейко@vk 10-07-2016 18:51 2649510

Поиск и замена текста в файле
 
Здравствуйте.
Прошу помощи.

Есть файл с именем 1.txt в нем последняя строчка заканчивается такими символами "текст::== ))"
Необходимо символы "== ))" перенести на новую строчку, т.е. вставить перенос строки <CR><LF>
Текст в кодировке ANSI.
Как это сделать с помощью bat файла?

Пробую следующее, не работает:

setlocal enabledelayedexpansion

Set "infile=D:\1.txt"
Set "find="== ))""
Set "replace=\n"== ))""

@echo off

setlocal enabledelayedexpansion
set COUNT=0
for /F "tokens=* delims=," %%n in (!infile!) do (
set LINE=%%n
set TMPR=!LINE:%find%=%replace%!
Echo !TMPR!>>1.txt
)
move 1.txt %infile%le%

alpap 10-07-2016 20:28 2649531

Код:

@echo off
set "f=1.txt"
<"%f%">$ (
 for /f "delims=" %%a in ('more') do @(
  echo %%a|>nul findstr/ec:"== ))" && (
  for /f "tokens=1,2 delims=:" %%b in ("%%~a") do @(
    echo %%b::
    echo %%c
  )
  ) || (
  echo %%a
  )
 )
)& move $ "1.txt"
exit

.

Дмитрий_Кульгейко@vk 10-07-2016 21:38 2649558

Опробовал код. Что-то не совсем так.
Переход на новую строку произошел, но вместо символов "== ))" стоит 0

NickM 10-07-2016 22:02 2649563

вот, надергал куски из сети ))
Код:

@echo off
SetLocal EnableExtensions EnableDelayedExpansion
 
Set infile=in.txt
Set outFile=out.txt

:: Узнаем количество строк в файле
for /f %%n in ( 'more ^< "!infile!" ^| find /c /v ""' ) do (
        set tail.count=%%n
)

:: Модифицируем две последние строки в файле
for /f "UseBackQ delims=" %%n in ("%infile%") do (
  set "LINE=%%n"
  set /a m+=1 
  if !m! EQU !tail.count! (goto funcR) else (echo=!LINE!>>"%outFile%")
)
:funcR
set LINE=%LINE:~0,-5%
echo=%LINE%>>"%outFile%"
echo.== ))>>"%outFile%"


alpap 10-07-2016 22:30 2649571

Дмитрий_Кульгейко@vk,
А не подскажете, почему у меня все работает? Даже кодировку такую поставил, хоть тут она роли и не играет (читабельность - не в счет):
Файл 138004

alpap 10-07-2016 22:32 2649572

Подозреваю что в файле далеко не "текст::== ))", выложите файл сюда, посмотрим.

Дмитрий_Кульгейко@vk 10-07-2016 22:41 2649574

Вложений: 1
Изначально файл такой как во вложении. Числа в имени файла меняются.

Дмитрий_Кульгейко@vk 10-07-2016 22:57 2649579

To: alpap
Если убираю все кроме последней строки, ваш код работает.

To: NickM
Ваш код тоже работает если у файла постоянное имя.

alpap 11-07-2016 00:07 2649590

Дмитрий_Кульгейко@vk,
Мало того что в строках еще есть :, откуда мне знать, а он у меня в разделителях, так еще вы приводите строку "текст::== ))", а на самом деле "текст::==))":
Код:

@echo off
set "f=1.txt"
<"%f%">$ (
 for /f "delims=" %%a in ('more') do @(
  echo %%a|>nul findstr/ec:"==))" && (
  for /f "tokens=1* delims==" %%b in ("%%~a") do @(
    echo %%b
    echo ==%%c
  )
  ) || (
  echo %%a
  )
 )
)
move $ "1.txt"
exit

.

megaloman 11-07-2016 08:56 2649653

Код:

@Echo Off

        Set "Sep===))"
        Set /A NSep=4
        Set "FName=ma2_20166_28.txt"

SetLocal EnableExtensions EnableDelayedExpansion
Call :ReLast "%FName%"
GoTo :Eof

:ReLast

Del "%~1.tmp" 2>nul
 
Set "Str="
FOR /F "usebackq delims=" %%s IN (`type "%~1"`) DO (
        If Not "!Str!"=="" >>"%~1.tmp" Echo !Str!
        Set "Str=%%s"
)
If Not "!Str:~-%NSep%!"=="%Sep%" Del "%~1.tmp" 2>nul & GoTo :Eof
If "!Str:~0,-%NSep%!"=="" Del "%~1.tmp" 2>nul & GoTo :Eof

>>"%~1.tmp" Echo !Str:~0,-%NSep%!
>>"%~1.tmp" Echo !Str:~-%NSep%!
Move /Y "%~1.tmp" "%~1" >nul
GoTo :Eof

Дмитрий_Кульгейко@vk, Основные действия оформлены в виде процедуры, возможно, Вам потом захочется еще сделать цикл по файлам. Скрипт не изменит файл, у которого последняя строка
Код:

==))

Дмитрий_Кульгейко@vk 11-07-2016 11:13 2649714

To: alpap

Действительно моя ошибка. Теперь работает.

Но как теперь применить данный код ко всем подобным файлам т.е. файлы в названии имеют маску ma2_годмесяц_день.txt

При подставленный set "f=ma2_*.txt" не находит путь.

megaloman 11-07-2016 11:50 2649741

Дмитрий_Кульгейко@vk, Предчувствия меня не обманули :), замените кусок кода из моего предыдущего поста, и будет Вам желаемое:
Код:

@Echo Off

        Set "Sep===))"
        Set /A NSep=4
        Set "FName=ma2_*.txt"

SetLocal EnableExtensions EnableDelayedExpansion
For  %%f IN ("%FName%") DO Call :ReLast "%%f"
GoTo :Eof

FName может быть указан и полным путём, например,
Set "FName=C:\ku-ku\tra la la\ma2_*.txt"
И далее как в предыдущем посте
Код:

:ReLast

Del "%~1.tmp" 2>nul
 
Set "Str="
FOR /F "usebackq delims=" %%s IN (`type "%~1"`) DO (
        If Not "!Str!"=="" >>"%~1.tmp" Echo !Str!
        Set "Str=%%s"
)
If Not "!Str:~-%NSep%!"=="%Sep%" Del "%~1.tmp" 2>nul & GoTo :Eof
If "!Str:~0,-%NSep%!"=="" Del "%~1.tmp" 2>nul & GoTo :Eof

>>"%~1.tmp" Echo !Str:~0,-%NSep%!
>>"%~1.tmp" Echo !Str:~-%NSep%!
Move /Y "%~1.tmp" "%~1" >nul
GoTo :Eof

А если файлы и переименовать нужно
как в Вашей предыдущей теме
Код:

@Echo Off

        Set "Sep===))"
        Set /A NSep=4
        Set "FName=ma2_?????_??.txt"
        Set "Pref=12345_5_"

SetLocal EnableExtensions EnableDelayedExpansion
For  %%f IN ("%FName%") DO Call :ReLast "%%f"
GoTo :Eof

:ReLast

Del "%~1.tmp" 2>nul
 
Set "Str="
FOR /F "usebackq delims=" %%s IN (`type "%~1"`) DO (
        If Not "!Str!"=="" >>"%~1.tmp" Echo !Str!
        Set "Str=%%s"
)
If Not "!Str:~-%NSep%!"=="%Sep%" Del "%~1.tmp" 2>nul & GoTo :Eof
If "!Str:~0,-%NSep%!"=="" Del "%~1.tmp" 2>nul & GoTo :Eof

>>"%~1.tmp" Echo !Str:~0,-%NSep%!
>>"%~1.tmp" Echo !Str:~-%NSep%!

Set "Name=%~n1"
Set "Name2=0!Name:~8,-3!"
Set "Name=%Pref%!Name:~6,2!!Name2:~-2!!Name:~-2!%~x1"

Move /Y "%~1.tmp" "%~dp1%Name%" >nul
If Exist "%~dp1%Name%" echo Del "%~1" 
GoTo :Eof

Если уберёте echo, то исходный файл будет удалён

alpap 11-07-2016 12:58 2649787

Дмитрий_Кульгейко@vk,
для моего кода изменения такие:
Код:

@echo off
set "d=C:\papka"
for /f "delims=" %%A in ('dir/a-d/b "%d%\ma2_*.txt"') do (
 <"%%A">$ (
  for /f "delims=" %%a in ('more') do @(
  echo %%a|>nul findstr/ec:"==))" && (
    for /f "tokens=1* delims==" %%b in ("%%~a") do @(
    echo %%b
    echo ==%%c
    )
  ) || (
    echo %%a
  )
  )
 )
 move $ "%d%\%%A"
)
exit

или используйте лучше код megaloman, удобнее.

Дмитрий_Кульгейко@vk 11-07-2016 13:34 2649808

To: megaloman
Ура все работает. Спасибо всем за помощь.

To: alpap
Ваш код тоже работает, но результат сохраняет в файле с именем %A

Посоветуйте книгу по написанию кода в cmd/bat.

alpap 11-07-2016 14:03 2649826

Цитата:

Цитата Дмитрий_Кульгейко@vk
но результат сохраняет в файле с именем %A »

исправил.

Цитата:

Цитата Дмитрий_Кульгейко@vk
Посоветуйте книгу по написанию кода в cmd/bat. »

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

Дмитрий_Кульгейко@vk 12-07-2016 17:51 2650206

Спасибо.

Дмитрий_Кульгейко@vk 12-07-2016 18:42 2650224

alpap, спасибо буду учится.

megaloman, файлы действительно и переименовать надо было )))

По старому вопросу с датой в названии 316546, есть момент.
День оказывается тоже может состоять как из двух цифр, так и из одной.

megaloman 12-07-2016 19:28 2650232

Исправляю погрешности постановки: В имени файла день или месяц могут быть любыми (одно или двузначными)
Код:

@Echo Off

        Set "Sep===))"
        Set /A NSep=4
        Set "FName=D:\Delete\ma2_*_*.txt"
        Set "Pref=12345_5_"

SetLocal EnableExtensions EnableDelayedExpansion
For  %%f IN ("%FName%") DO Call :ReLast "%%f"
GoTo :Eof

:ReLast

Del "%~1.tmp" 2>nul
 
Set "Str="
FOR /F "usebackq delims=" %%s IN (`type "%~1"`) DO (
        If Not "!Str!"=="" >>"%~1.tmp" Echo !Str!
        Set "Str=%%s"
)
If Not "!Str:~-%NSep%!"=="%Sep%" Del "%~1.tmp" 2>nul & GoTo :Eof
If "!Str:~0,-%NSep%!"=="" Del "%~1.tmp" 2>nul & GoTo :Eof

>>"%~1.tmp" Echo !Str:~0,-%NSep%!
>>"%~1.tmp" Echo !Str:~-%NSep%!

FOR /F "usebackq tokens=2,3 delims=_" %%s IN ('%~n1') DO Set "YYYYMM=%%s" & Set "DD=0%%t"
Set "MM=0!YYYYMM:~4,2!
Set "Name=%~dp1%Pref%!YYYYMM:~2,2!!MM:~-2!!DD:~-2!%~x1"

move /Y "%~1.tmp" "!Name!" >nul
If Exist "!Name!" Del "%~1" 2>nul
GoTo :Eof

Путь подправьте (или уберите) в маске

Дмитрий_Кульгейко@vk 12-07-2016 19:50 2650240

Откорректировал год в двухзначный, не уверен что правильно, но работает )) получил:
Скрытый текст

@Echo Off

Set "Sep===))"
Set /A NSep=4
Set "FName=c:\TEMP\ma2_*_*.pdf"
Set "Pref=12345_5_"
Set "NewExt=.txt"

SetLocal EnableExtensions EnableDelayedExpansion
For %%f IN ("%FName%") DO Call :ReLast "%%f"
GoTo :Eof

:ReLast

Del "%~1.tmp" 2>nul

Set "Str="
FOR /F "usebackq delims=" %%s IN (`type "%~1"`) DO (
If Not "!Str!"=="" >>"%~1.tmp" Echo !Str!
Set "Str=%%s"
)
If Not "!Str:~-%NSep%!"=="%Sep%" Del "%~1.tmp" 2>nul & GoTo :Eof
If "!Str:~0,-%NSep%!"=="" Del "%~1.tmp" 2>nul & GoTo :Eof

>>"%~1.tmp" Echo !Str:~0,-%NSep%!
>>"%~1.tmp" Echo !Str:~-%NSep%!

FOR /F "usebackq tokens=2,3 delims=_" %%s IN ('%~n1') DO Set "YYYYMM=%%s" & Set "DD=0%%t"
Set "MM=0!YYYYMM:~4,2!
Set "Name=%~dp1%Pref%!YYYYMM:~2,2!!MM:~-2!!DD:~-2!%NewExt%"

move /Y "%~1.tmp" "!Name!" >nul
If Exist "!Name!" Del "%~1" 2>nul
GoTo :Eof

megaloman 12-07-2016 19:57 2650243

Дмитрий_Кульгейко@vk, Извините, забыл что год на выходе двузначный, в предыдущем посте я его исправил, в другой теме сейчас тоже сделаю, чтобы не плодить лишние посты

Дмитрий_Кульгейко@vk 12-07-2016 20:01 2650244

Да за что извиняться то. Это мне надо и значит я должен обо всем помнить)))
Значит я с годом угадал ?


Время: 19:45.

Время: 19:45.
© OSzone.net 2001-