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

sv_diz 04-01-2010 09:54 1310388

Как добавить текст в середину текстрового файла
 
Есть текстовый файл 1.txt:

__________________________
aaa

[paste]

ccc
__________________________

К примеру [paste] нужно заменить на bbb, при этом пустые строки должны остаться (FOR /F не помог)

El Sanchez 04-01-2010 17:05 1310626

Будем думать, что под [paste] подразумевается только 1 строка, а не целый абзац
Код:

@echo off
set "SRC=C:\Temp\1.txt"

for /f "usebackq tokens=*" %%a in ("%SRC%") do (
if not "%%a"=="" (
if "%%a"=="[paste]" (echo bbb>>tmp) else (echo %%a>>tmp)) else (echo.>>tmp)
)
copy /y tmp %SRC% 1>nul&&del /f /q tmp>nul


sv_diz 04-01-2010 23:25 1310974

El Sanchez, спасибо за внимание!!! Но вопрос остаётся открытым - я писал: -"при этом пустые строки должны остаться" это важно!!!

Из справки цикла FOR: По умолчанию /F передает первый отделенный пробелом элемент из каждой строки каждого файла. Пустые строки пропускаются.

El Sanchez 05-01-2010 14:44 1311382

Хех, вчера у меня этот сценарий работал, сегодня нет.
Вариант №2
Код:

@echo off
setlocal ENABLEDELAYEDEXPANSION
set "SRC=C:\Temp\1.txt"
set "ReplaceText=bbb"

set count=1
for /f "usebackq tokens=1* delims=:" %%a in (`findstr /in . "%SRC%"`) do call :func "%%a" "%%b" "%ReplaceText%"
endlocal
copy /y tmp %SRC% 1>nul&&del /f /q tmp>nul
goto :eof

:func
if not "%~1"=="!count!" (
set /a count+=1&echo.>>tmp
if "%~2"=="[paste]" (echo %~3>>tmp) else (echo %~2>>tmp)) else (
if "%~2"=="[paste]" (echo %~3>>tmp) else (echo %~2>>tmp))
set /a count+=1

P.S. Переменная ReplaceText не должна содержать спец. символов

Devils0411 05-01-2010 21:40 1311831

А что если сделать возможность, при запуске пакетника, он просил ввести что-то в переменную ReplaceText?
Например:
Код:

@echo off
setlocal ENABLEDELAYEDEXPANSION
set "SRC=C:\Temp\1.txt"
set /P ReplaceText=Enter the data in the variable :
set count=1
for /f "usebackq tokens=1* delims=:" %%a in (`findstr /in . "%SRC%"`) do call :func "%%a" "%%b" "%ReplaceText%"
endlocal
copy /y tmp %SRC% 1>nul&&del /f /q tmp>nul
goto :eof

:func
if not "%~1"=="!count!" (
set /a count+=1&echo.>>tmp
if "%~2"=="[paste]" (echo %~3>>tmp) else (echo %~2>>tmp)) else (
if "%~2"=="[paste]" (echo %~3>>tmp) else (echo %~2>>tmp))
set /a count+=1

Текст написанный красным будет отображаться при запуске пакетника с просьбой ввести данные в переменную. Соответственно в переменной ReplaceText будет находится та информация, которую вы ввели.

sv_diz 06-01-2010 23:57 1312881

El Sanchez, спасибо за проделанную работу!
Остались не решённые вопросы:
1. если пустых строк несколько в подряд, этот скрипт отрабатывает не корректно
2. в строчке пробел или несколько (исключительно)

El Sanchez 07-01-2010 13:31 1313200

Цитата:

Цитата sv_diz
1. если пустых строк несколько в подряд, этот скрипт отрабатывает не корректно »

Все верно, моя ошибка. Вариант №3:
Код:

@echo off
setlocal ENABLEDELAYEDEXPANSION
set "SRC=C:\Temp\1.txt"
set /p ReplaceText=Заменяемый текст :
set /p ReplaceableText=Замещаемый текст :
set count=1
for /f "usebackq tokens=1* delims=:" %%a in (`findstr /in . "%SRC%"`) do call :func "%%a" "%%b" "%ReplaceText%"
endlocal
copy /y tmp %SRC% 1>nul&&del /f /q tmp>nul
goto :eof

:func
set /a Diff=%~1-!count!
if %Diff% GTR 0 (
        for /l %%a in (1,1,%Diff%) do (set /a count+=1&echo.>>tmp)
        if /i "%~2"=="%ReplaceableText%" (echo %~3>>tmp) else (echo %~2>>tmp)
) else (
        if /i "%~2"=="%ReplaceableText%" (echo %~3>>tmp) else (echo %~2>>tmp)
)
set /a count+=1

Цитата:

Цитата sv_diz
2. в строчке есть пробел или несколько »

Не знаю я как строку, состоящую из одного или нескольких пробелов записать в файл.

sv_diz 07-01-2010 23:37 1313684

уважаемый El Sanchez, ещё раз спасибо за помощь начинающему
последний вариант bat-файла не обрабатывает следующий текст:

///////////////////////
1
<
>
.
//////////////////////

можно чтото сделать?

El Sanchez 08-01-2010 19:11 1314406

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

Цитата sv_diz
не обрабатывает следующий текст »

Потому что средствами cmd довольно-таки сложно обрабатывать богатый спецсимволами текст, поэтому без спецсредств не обойтись. Предлагаю вариант 4 с применением утилиты sed.

Код:

@echo off

set "SRC=C:\Temp\1.txt"
set "SedReplaceableText="
set /p ReplaceText=Заменяемый текст :
set /p ReplaceableText=Замещаемый текст :

for /f "tokens=1* delims==" %%a in ('set ReplaceText^|sed -e s/\\/\\\\/g^;s/\[/\\\[/g^;s/\./\\\./g^;s/\*/\\\*/g^;s/\$/\\\$/g') do set "ReplaceText=%%b"
for /f "tokens=1* delims==" %%a in ('set ReplaceableText^|sed -e s/\\/\\\\/g^;s/\[/\\\[/g^;s/\./\\\./g^;s/\*/\\\*/g^;s/\$/\\\$/g') do set "ReplaceableText=%%b"
sed -e /"%ReplaceableText%"/s//"%ReplaceText%"/<"%SRC%">>tmp
copy /y tmp %SRC% 1>nul&&del /f /q tmp>nul

P.S. С sed-ом я не особо дружу, регулярное выражение сделал как смог. (
P.P.S. Символ "^" не отрабатывается. (

Devils0411 08-01-2010 19:34 1314430

El Sanchez, помоему данное задание из разряда программирования на C++

amel27 09-01-2010 11:17 1315022

CMD/BAT - [решено] Замена строк конфига

BigBoo 14-04-2011 11:25 1658029

Похожий вопрос, но задача несколько иная. К примеру, как в шапке, 1.txt:
Код:

...
aaa=1

[paste]
bbb=1
ccc=1
...

Задача: Нужен скрипт, изменяющий в секции [paste] значение ccc=1 на ccc=0, если параметра ccc не существует, добавить ccc=0 именно в эту секцию.

amel27 14-04-2011 14:29 1658196

Цитата:

Цитата BigBoo
скрипт, изменяющий в секции [paste] значение ccc=1 на ccc=0, если параметра ccc не существует, добавить ccc=0 именно в эту секцию »

Код:

@echo off

CALL:INISET 1.ini paste ccc 0
EXIT

:INISET  %file_path% %section% %parm% %val%
::-----------------------------------------
SETLOCAL DisableDelayedExpansion
set $sn= & set $vf=0& set "$ft=%TEMP%\%RANDOM%%RANDOM%.tmp"
(for /f "tokens=1,2* delims==:" %%a in ('findstr /n "$" "%~1"') do (
 set "$b=%%b"& set "$c=%%c"
 SETLOCAL EnableDelayedExpansion
 if "!$b:~0,1!"=="[" set "$sn=!$b:~1,-1!"
 set $lf=_& if /i "!$sn!"=="%~2" if /i "!$b!"=="%~3" set "$lf="
 if defined $c set "$c==!$c!"
 if defined $lf echo/!$b!!$c!
 if "!$sn!"=="%~2" if "!$vf!"=="0" set $vf=1& echo %~3=%~4
 for /f "tokens=1,2 delims=:" %%i in ("!$sn!:!$vf!") do (
ENDLOCAL& set "$sn=%%i"& set "$vf=%%j")))>"%$ft%"
copy /y "%$ft%" "%~1">nul&& del "%$ft%"
::----------------
ENDLOCAL& GoTo:EOF


BigBoo 18-04-2011 22:47 1661267

Попробовал Ваш скрипт, что-то не так. Он просто удаляет параметр "ссс" и ничего более не делает. :(

Foreigner 18-04-2011 23:08 1661289

Код:

gsar "-s[paste]" "-rbbb" -o 1.txt

amel27 19-04-2011 06:24 1661444

Цитата:

Цитата BigBoo
Он просто удаляет параметр "ссс" и ничего более не делает »

исправил, была ошибка в случае если файл начинался не с имени секции

BigBoo 19-04-2011 19:01 1661885

amel27, всё работает, но в моём случае значение параметра содержит символы, в результате скрипт не срабатывает, то есть к примеру так:
Код:

CALL:INISET 1.ini paste ccc ""a 1","b 2","c 3""
Убираю внутренние кавычки - работает, но хотелось, чтоб они обрабатывались, а также возможна ли обработка символа | ?

amel27 20-04-2011 05:16 1662094

Цитата:

Цитата BigBoo
значение параметра содержит символы »

придется передавать не по значению, а по ссылке на переменную, содержащую это значение:
Код:

@echo off

set "$val="a 1","b 2"|"c 3""
CALL:INISET 1.ini paste ccc $val
EXIT

:INISET  file_path section parm ByRef val
::---------------------------------------
SETLOCAL DisableDelayedExpansion
set $sn= & set $vf=0& set "$ft=%TEMP%\%RANDOM%%RANDOM%.tmp"
(for /f "tokens=1,2* delims==:" %%a in ('findstr /n "$" "%~1"') do (
 set "$b=%%b"& set "$c=%%c"
 SETLOCAL EnableDelayedExpansion
 if "!$b:~0,1!"=="[" set "$sn=!$b:~1,-1!"
 set $lf=_& if /i "!$sn!"=="%~2" if /i "!$b!"=="%~3" set "$lf="
 if defined $c set "$c==!$c!"
 if defined $lf echo/!$b!!$c!
 if defined %~4 (set $4=!%~4!) else set "$4=%~4"
 if "!$sn!"=="%~2" if "!$vf!"=="0" set $vf=1& echo %~3=!$4!
 for /f "tokens=1,2 delims=:" %%i in ("!$sn!:!$vf!") do (
ENDLOCAL& set "$sn=%%i"& set "$vf=%%j")))>"%$ft%"
copy /y "%$ft%" "%~1">nul&& del "%$ft%"
::----------------
ENDLOCAL& GoTo:EOF


BigBoo 20-04-2011 12:15 1662273

amel27, Всё бы хорошо, но вот так работает:
Код:

set "$val="a 1","b 2"|"c 3""
А вот так - нет:
Код:

set "$val="a 1","b 2""|c 3""

amel27 20-04-2011 12:41 1662287

Цитата:

Цитата BigBoo
А вот так - нет:
Код:
set "$val="a 1","b 2""|c 3"" »

для такой строки можно использовать код (намеренно заменил "," на "|"):
Код:

set $val="a 1"^|"b 2""|c 3"
Из этого примера видно, что спецсиволы вне кавычек нужно экранировать символом "^". Если мы теперь возьмём всю команду SET в кавычки, то произойдёт инверсия: всё что было в кавычках окажется за ними и наоборот, это нужно учесть при экранировании спецсимволов:
Код:

set "$val="a 1"|"b 2""^|c 3""

BigBoo 20-04-2011 16:32 1662423

amel27, А можно ли так же использовать переменную для имени параметра, то есть в данном примере вместо ссс. Так работать не хочет:
Код:

set "$ByRef="a 1","b 2","c 3"" 
set "$val="a 1","b 2","c 3""
CALL:INISET 1.ini paste $ByRef $val


amel27 20-04-2011 16:48 1662441

Цитата:

Цитата BigBoo
можно ли так же использовать переменную для имени параметра »

можно совместить оба способа (по аналогии):
Код:

@echo off

set "$par=ccc"
set "$val="a 1","b 2","c 3""
CALL:INISET 1.ini paste $par $val
EXIT

:INISET  %file_path% %section% parm val
::---------------------------------------
SETLOCAL DisableDelayedExpansion
set $sn= & set $vf=0& set "$ft=%TEMP%\%RANDOM%%RANDOM%.tmp"
(for /f "tokens=1,2* delims==:" %%a in ('findstr /n "$" "%~1"') do (
 set "$b=%%b"& set "$c=%%c"
 SETLOCAL EnableDelayedExpansion
 if defined %~3 (set $3=!%~3!) else set "$3=%~3"
 if defined %~4 (set $4=!%~4!) else set "$4=%~4"
 if "!$b:~0,1!"=="[" set "$sn=!$b:~1,-1!"
 set $lf=_& if /i "!$sn!"=="%~2" if /i "!$b!"=="!$3!" set "$lf="
 if defined $c set "$c==!$c!"
 if defined $lf echo/!$b!!$c!
 if "!$sn!"=="%~2" if "!$vf!"=="0" set $vf=1& echo !$3!=!$4!
 for /f "tokens=1,2 delims=:" %%i in ("!$sn!:!$vf!") do (
ENDLOCAL& set "$sn=%%i"& set "$vf=%%j")))>"%$ft%"
copy /y "%$ft%" "%~1">nul&& del "%$ft%"
::----------------
ENDLOCAL& GoTo:EOF

> ByRef - префикс, обозначающий использование параметра по ссылке;
> очень странное имя для параметра... на всякий случай: оно не должно содержать символов ":" и "="

BigBoo 20-04-2011 18:02 1662502

amel27, спасибо, теперь всё работает как надо.
Цитата:

Цитата amel27
очень странное имя для параметра »

Имелись ввиду ini-файлы "Оперы", а именно параметр standard_menu.ini:
Код:

[Quick Preferences Menu]
Item, "Speed Dial - логотип вместо страницы" = Set preference,"User Prefs|Thumbnail Logo Score Logo URL=75" | Set preference,"User Prefs|Thumbnail Logo Score Logo URL=0"

Скрипт задумывался как часть твика для установленной Opera 11.10.

BigBoo 20-04-2011 18:40 1662518

Попробовал на реальном standard_menu.ini и обнаружилась новая проблема, связанная с кодировкой. Дело в том, что standard_menu.ini в кодировке UTF-8, и после отработки скрипта вместо русских букв получаем:
Код:

Item, "Speed Dial - ⨯ ⢮ ⣠穢= и т.д.
Хоть CMD-файл в OEM-866, ANSI-1251 - всё равно, а если для прикола сохранить в UTF-8 :) - скрипт такое с standard_menu.ini вытворяет, мама не горюй!:lol: Извиняюсь, может несколько не в эту тему, как в скрипте указать, что русские буквы должны находиться в UTF-8?
p.s. С кодировкой standard_menu.ini всё в порядке, скрипт её не меняет, если русские буквы не использовать - всё отрабатывает корректно!

Iska 20-04-2011 19:03 1662541

BigBoo, возможно, Вам стоит перейти на использование WSH, а ещё лучше — PowerShell.

amel27 21-04-2011 07:05 1662809

Цитата:

Цитата BigBoo
обнаружилась новая проблема, связанная с кодировкой »

именно поэтому нужно сразу давать пример, максимально приближенный к "боевым" условиям, а не тот куцый, что из первого поста
Цитата:

Цитата BigBoo
а если для прикола сохранить в UTF-8 - скрипт такое с standard_menu.ini вытворяет, мама не горюй »

на самом деле, если всё аккуратно сделать - убрать BOM и заэкранировать спецсимволы, то всё работает... просто в батнике в команде SET вместо русских букв будут "крякозябки", но ему по большому счету всё равно что менять... и понятное дело, учет регистра букв работать не будет

напрямую батник с UTF8 работать не может, так как для Windows "родными" являются OEM/ANSI/UTF-16 кодировки, но можно сделать предварительное преобразование в любую из этих кодировок, а после обработки вернуть в исходную (UTF8), вот пример для исходного файла UTF-8 with BOM:
читать дальше »
Код:

@echo off

set $par=Item, "Speed Dial - логотип вместо страницы"
set $val=Set preference,"User Prefs|Thumbnail Logo Score Logo URL=75" ^| Set preference,"User Prefs|Thumbnail Logo Score Logo URL=0"

CALL:INISET 1.txt paste $par $val
EXIT

:INISET  %utf8_file_with_BOM% %section% parm val
::----------------------------------------------
SETLOCAL DisableDelayedExpansion
set $sn= & set "$t1=%TEMP%\%RANDOM%%RANDOM%.tmp"
set $vf=0& set "$t2=%TEMP%\%RANDOM%%RANDOM%.tmp"
chcp 65001|cmd/u/c Type "%~1">"%$t1%"&chcp 866>nul

(for /f "tokens=1* delims==]" %%a in ('type "%$t1%"^|find/n /v ""') do (set "$b=%%b"
 SETLOCAL EnableDelayedExpansion
 if "!$b:~0,1!"=="[" set "$sn=!$b:~1,-1!"
 for /f "delims==" %%p in ("!$b!") do set "$p=%%p"
 if /i not "!$sn!"=="%~2" (echo/!$b!) else (
 if /i not "!$p!"=="!%~3!" if /i not "!$p!"=="!%~3! " echo/!$b!)
 if "!$sn!"=="%~2" if "!$vf!"=="0" set $vf=1& echo/!%~3!=!%~4!
 for /f "tokens=1,2 delims=:" %%i in ("!$sn!:!$vf!") do (
 ENDLOCAL& set "$sn=%%i"& set "$vf=%%j"
)))>"%$t2%"

set/p $="я╗┐">"%$t1%"<nul
(for /f "usebackq delims=" %%a in ("%$t2%") do (set "$a=%%a"
CHCP 65001|cmd/v/c "echo/!$a!"&CHCP 866>nul))>>"%$t1%"

copy /y "%$t1%" "%~1">nul&& del "%$t1%"
::----------------
ENDLOCAL& GoTo:EOF


P.S. красным выделен BOM для UTF-8, лучше скопировать его с любого UTF8-текстовика
P.P.S. если исходный файл не содержит BOM, код придется изменить

BigBoo 21-04-2011 10:57 1662949

Цитата:

Цитата amel27
красным выделен BOM для UTF-8, лучше скопировать его с любого UTF8-текстовика »

Если честно, так и не понял. Что имеется ввиду под "скопировать BOM с любого UTF8-текстовика" и как это сделать?
И ещё вопрос: cmd-файл со скриптом в Вашем последнем примере сохраняется в OEM-866?

amel27 21-04-2011 11:53 1662996

Цитата:

Цитата BigBoo
cmd-файл со скриптом в Вашем последнем примере сохраняется в OEM-866? »

да
Цитата:

Цитата BigBoo
Что имеется ввиду под "скопировать BOM с любого UTF8-текстовика" и как это сделать? »

- создать в блокноте произвольный текст и сохранить его в файл в формате UTF-8;
- открыть полученный UTF8-файл в текстовом редакторе как DOS-текст (блокнот не поддерживает, я использую FAR);
- скопировать первые три спецсимвола (BOM) в отмеченное место батника;

P.S. Всё это имеет смысл только если обрабатываемые файлы Opera содержат BOM, в противном случае скрипт придется переделывать.

BigBoo 21-04-2011 20:51 1663423

amel27, испробовал Ваш скрипт с учётом "BOM". Скрипт зацикливается на ошибке и далее иероглифы:
Код:

Достигнут уровень рекурсии, максимально возможный для команды SETLOCAL.
Если из INI-файла удалить всё, кроме нужной секции - отрабатывает, вставляя по одному символу в строку столбиком, где русские буквы - всё те же крякозябры.

Foreigner 21-04-2011 22:42 1663497

BigBoo,
Мне кажется вы выбрали не тот инструмент, голые батники плохо работают с текстом, тем более в utf8, а если конфиг большой, то есть вероятность, что он его вообще не пропарсит. Если вы хотите твик оперы, то на мой взгляд, было бы проще и надежней просто заменить файл конфига другим, модифицированным.

BigBoo 21-04-2011 23:09 1663514

Цитата:

Цитата Foreigner
проще и надежней просто заменить файл конфига другим, модифицированным »

в принципе так я и делаю, просто интересно скриптом, чисто из познавательных соображений.
Если с CMD никак, будем думать о WSH.

amel27 22-04-2011 05:13 1663607

Цитата:

Цитата BigBoo
Скрипт зацикливается на ошибке и далее иероглифы »

не могу воспроизвести ошибку, выложите в архиве: INI-файл + сам батник

Цитата:

Цитата Foreigner
Мне кажется вы выбрали не тот инструмент.»

это вопрос скорее философский, чем технический - так или иначе, с использованием "сторонних" решений или без них задачу можно решить любым инструментом... можно запускать NETSH из WSH и считать это чистым WSH-решением, с равным успехом можно задействовать WSH из батников, в конечном счете всё зависит от конкретной задачи и глубины её проработки


учитывая свойства INI-файла, я бы вообще не парился с правкой "середины текстового файла", а подошел с другой стороны:

- отфильтровать нужную строку через FIND/FINDSTR (вероятность того, что параметр встретится в другой секции =0);
- добавил в конец INI-файла кусок секции с одним нужным параметром;
- при запуске Opera автоматически сольёт все одноименные секции в одну.

это не решает вопроса с кодировкой, но снимает проблему парсинга содержимого

Foreigner 22-04-2011 07:25 1663618

Цитата:

Цитата amel27
это вопрос скорее философский »

Я бы сказал, что это вопрос удобства. Писать портянку или использовать готовый нструмент:
Код:

@echo off
setlocal

set "file=Full\Path\To\file.ini"

:: Добавить или переписать параметр

nircmdc inisetval "%file%" "section 1" "key" "value"
nircmdc inisetval "%file%" "section 2" "testkey" "|^\><#@&&"

http://www.nirsoft.net/utils/nircmd.html

Iska 22-04-2011 07:51 1663625

Главная беда с ini-файлами в том, что при переходе с Win3.x на Win9.x/WinNT почему-то, в эйфории, посчитали, что впредь ini-файлы будут не востребованы, и не добавили их встроенную поддержку ни в пакетные файлы, ни в Windows Script Host, ни, тем паче, в нынешний PowerShell.

amel27 22-04-2011 09:06 1663659

Цитата:

Цитата Foreigner
nircmdc »

UTF-8 без костылей не осилит, да и заявленный файл не похож на обычный INI,
с такими странными именами параметров nircmd его просто проигнорирует:
Код:

Item, "Speed Dial - логотип вместо страницы" = ...

BigBoo 22-04-2011 10:47 1663740

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

Цитата amel27
выложите в архиве: INI-файл + сам батник »


amel27 22-04-2011 12:07 1663813

BigBoo, как и предполагал - INI-файлы не содержат BOM, если добавить - всё работает... предупреждал же:
Цитата:

Цитата amel27
Всё это имеет смысл только если обрабатываемые файлы Opera содержат BOM, в противном случае скрипт придется переделывать »

определитесь сначала с кодировкой исходных файлов... кстати, в моей Опере все INI с BOM

BigBoo 22-04-2011 12:26 1663834

Цитата:

Цитата amel27
как и предполагал - INI-файлы не содержат BOM »

Как же так, пользовался AkelPad - в строке состояния определяет: Win 65001 (UTF-8) *BOM!

amel27 22-04-2011 12:42 1663849

Цитата:

Цитата BigBoo
Как же так »

а проверить? ;)
...но мы ушли в сторону, вот пара тем (там есть и другие WSH/CMD варианты):

CMD/BAT - [решено] Автоматическая смена кодировки .txt файлов
CMD/BAT - [решено] Изменение кодировки txt файла из ANSI в UTF-16 LE

Foreigner 23-04-2011 09:38 1664266

Цитата:

Цитата Iska
и не добавили их встроенную поддержку ни в пакетные файлы, ни в Windows Script Host, ни, тем паче, в нынешний PowerShell. »

Но по крайней мере в PowerShell гораздо проще работать с текстом. Вот пример:
Код:

$file = gc test.ini

$sections = @()
switch -regex ($file) {

    "\[.*\]" {
   
              $sec = @{}
              $sec.name = $_
              $sec.param = @()
              $sec.value = @()
     
              $sections += $sec
   
            }

    ".*=.*" {
   
              $sec.param += $($_ -replace '(.*)=.*', '$1')
              $sec.value += $($_ -replace '.*=(.*)', '$1')
               
            }

}

for ($i = 0; $i -le $($sections.count-1); $i++) {

    $sections[$i].name
    0..$($sections[$i].param.count-1) | % {

        "$($sections[$i].param[$_]) = $($sections[$i].value[$_])"

    }

}

Здесь просто выводится содержимое ini-файла, но не построчно, а как именованные свойства ini. Т.е. к любому из них можно обратиться не как к строке.

Iska 23-04-2011 10:28 1664275

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

BigBoo 03-04-2012 14:07 1892536

Код:

For /F "Tokens=2*" %%I In ('Reg Query "HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders" /V Personal') Do Set Personal=%%J
start "" /wait "nircmd.exe" inisetval "%AppData%\Opera\Opera\operaprefs.ini" "User Prefs" "Download Directory" "%Personal%\Закачки"

В итоге в operaprefs.ini: Download Directory=F:\ 𐆿𐊺𐊶𐉶\Ƞ롷릍
Как решить проблему с кодировкой, чтобы было F:\Мои документы\Закачки

AdBes 06-02-2014 17:41 2304161

Доброго времени суток.
Помогите, пожалуйста.

Задача: изменить текст в txt-файле.
Решение:
Код:

@echo off
cls
setlocal enabledelayedexpansion
:: указываем файл
        set file=.\WEB-INF\classes\tops\unicus\resources\unicus.properties
:: ввести строку для поиска
        set /p search=[enter text to search]
:: ввести строку для замены
        set /p change=[enter the text to change]
        @echo off
        setlocal enabledelayedexpansion
        set COUNT=0
:: ищем строку и заменяем
        for /F "usebackq tokens=*" %%s in (!file!) do (
                        set LINE=%%s
                        ::замена текущей строки
                        set TMPR=!LINE:%search%=%change%!
                        ::добавляем строку к временному файлу
                        Echo.!TMPR!>>TMP.TXT                               
        )
        :: Делаем резервное копирование исходного файла, на случай что что то пойдет не так…
        copy %file% %file%.bak
        :: Заменяем исходный файл временным
        move TMP.TXT %file%

Проблема: при замене текста удаляются пустые строки, а не должны

Пробовала разные варианты, результат одинаковый: текст меняет и пустые строки удаляет.

Подскажите, пожалуйста, что делаю неправильно?
Заранее спасибо.

Georgio 06-02-2014 19:29 2304237

Код:

@echo off
:: указываем файл
    set file=.\web-inf\classes\tops\unicus\resources\unicus.properties
:: ввести строку для поиска
    set /p search=[enter text to search]
:: ввести строку для замены
    set /p change=[enter the text to change]

 for /f %%i in ('find /c /v ""^<"%file%"') do set n=%%i
(
 for /l %%i in (1 1 %n%) do (
  set LINE=
  set /p "LINE="
  if defined LINE call set /p"=%%LINE:%search%=%change%%%"<nul
  if %%i==%n% goto exit
  echo.
 )
)<"%file%">tmp.txt

:exit
:: делаем резервное копирование исходного файла
    copy "%file%" "%file%.bak">nul
:: заменяем исходный файл временным
    move tmp.txt "%file%">nul
exit /b


AdBes 07-02-2014 13:05 2304742

Georgio, Большое спасибо.
Разбирала написанный Вами код, и к сожалению, не смогла найти ответы на некоторые возникшие вопросы.
Буду очень благодарна, если Вы на них ответите.

Разбор строки
Код:

for /f %%i in ('find /c /v ""^<"%file%"') do set n=%%i
Вопросы:
  1. Ключи команды find /c /v выполняют противоположные действия, подскажите, пожалуйста, правильно ли я понимаю, что при сочетании этих ключей получается более точные поиск искомой строки?
  2. Правильно ли я понимаю, что это "" обозначение пустой строки?
  3. Подскажите, пожалуйста, зачем выполняется экранирование ^<


Разбор строки
Код:

for /l %%i in (1 1 %n%) do (
Вопрос:
  1. Подскажите, пожалуйста, что означает (1 1 %n%) ?


Разбор строки
Код:

set LINE=
Вопрос:
  1. Подскажите, пожалуйста, это добавление пустой строки?


Разбор строки
Код:

set /p "LINE="
Вопрос:
  1. Ключ /p означает ввод значения с клавиатуры, но в данном случае этого не происходит. Подскажите, пожалуйста, почему?


Разбор строки
Код:

if defined LINE call set /p"=%%LINE:%search%=%change%%%"<nul
Вопросы:
  1. Двойной процент %% означает вывод на экран символа %. Сомневаюсь, что в данном случае подразумевается именно вывод символа %. Расшифруйте, пожалуйста, назначение процентов в данной строке
  2. Сочетание >nul означает запрет вывода на экран команды и ее действия. Подскажите, пожалуйста, что означает сочетание <nul

Заранее спасибо.

Iska 07-02-2014 13:58 2304770

Цитата:

Цитата AdBes
Ключи команды find /c /v выполняют противоположные действия, подскажите, пожалуйста, правильно ли я понимаю, что при сочетании этих ключей получается более точные поиск искомой строки? »

Нет. Командой «find /c /v ""^<"%file%"» осуществляется подсчёт числа строк во входном файле «%file%». «/v ""» используется для вывода всех строк, а «/c» их считает.
Цитата:

Цитата find.exe /?
/V Вывод всех строк, НЕ содержащих заданную строку.
/C Вывод только общего числа строк, содержащих заданную строку.

Затем в цикле «for /f» производится разбор вывода команды «find», и выведенное ею число строк файла «%file%» присваивается переменной окружения «n».

Цитата:

Цитата AdBes
Правильно ли я понимаю, что это "" обозначение пустой строки? »

Да.

Цитата:

Цитата AdBes
Подскажите, пожалуйста, зачем выполняется экранирование ^< »

Потому что иначе символ перенаправления «<» будет воспринят циклом разбора «for /f», а не передан команде «find».

Цитата:

Цитата AdBes
Подскажите, пожалуйста, что означает (1 1 %n%) ? »

Цитата:

Цитата for /?
FOR /L %переменная IN (начало,шаг,конец) DO команда [параметры]

Набор раскрывается в последовательность чисел с заданными началом, концом и шагом приращения. Так, набор (1,1,5) раскрывается в (1 2 3 4 5), а набор (5,-1,1) заменяется на (5 4 3 2 1).

В данном случае «%%i» будет раскрываться, начиная с «1», с шагом «1» и до полученного числа строк файла «%file%», которое было выше сохранено в переменной окружения «n».

Цитата:

Цитата AdBes
Подскажите, пожалуйста, это добавление пустой строки? »

Нет. Это удаление переменной окружения «LINE».

Цитата:

Цитата AdBes
Ключ /p означает ввод значения с клавиатуры, но в данном случае этого не происходит. Подскажите, пожалуйста, почему? »

Потому что значимым здесь является весь блок команд:
Код:

(
        for /l %%i in (1 1 %n%) do (
                set LINE=
                set /p "LINE="
                if defined LINE call set /p"=%%LINE:%search%=%change%%%"<nul
                if %%i==%n% goto exit
                echo.
        )
)<"%file%">tmp.txt

и ввод в «set /p "LINE="» осуществляется из файла «%file%», а вывод из того же блока команд — в файл «tmp.txt». Ввод в «set /p "LINE="» при этом осуществляется построчно — по одной строке на каждом цикле прохода «for /l».

Цитата:

Цитата AdBes
Двойной процент %% означает вывод на экран символа %. »

Не означает вывод. Рассматривайте команду:
Код:

… call set /p"=%%LINE:%search%=%change%%%"<nul
целиком. Она распадается на две команды — собственно вызов «call» и вычисляемая при его вызове подкоманда «set /p"=%LINE:«Здесь вычисленное при вызове call значение переменной окружения «search»»=«Здесь вычисленное при вызове call значение переменной окружения «change»»%"<nul».

Цитата:

Цитата AdBes
Сочетание >nul означает запрет вывода на экран команды и ее действия. »

Тоже неверное толкование. «>nul» означает перенаправление стандартного потока вывода команды в пустое устройство («nul»). Именно поэтому видимым следствием такого перенаправления может быть отсутствие вывода команды на экран.

Цитата:

Цитата AdBes
Подскажите, пожалуйста, что означает сочетание <nul»

Обратное. «<nul» — перенаправление стандартного потока ввода команды на ввод из пустого устройства («nul»). Для любой команды, ожидающей ввода строки из стандартного потока ввода, сие означает ввод пустой строки.

Констатируя, можем сказать, что в данном случае вся строка:
Код:

if defined LINE call set /p"=%%LINE:%search%=%change%%%"<nul
означает примерно следующее:
Цитата:

Если переменная окружения LINE существует (т.е., очередная строка текста из файла «%file%», сохранённая в «LINE», оказалась не пуста), то вывести эту строку (<nul set /p Var=%LINE%), заменив в ней «search» на «change».

AdBes 10-02-2014 11:28 2306430

Iska, большое спасибо.


Время: 01:53.

Время: 01:53.
© OSzone.net 2001-