我是这方面的新手,所以请放轻松。我正在尝试自动化一个过程,在此过程中我更改了特定服务的端口。端口在文件streamstack.exe.config中确定。我有一些东西可以找到并替换文件中的特定字符串,但是在某些情况下,我不知道定义的端口号。是否可以找到包含通配符的字符串并替换为预定义的字符串?例如找到"localhost:.*"
并替换为"localhost:80"
?
我已经可以将findstr
与wildcard
一起使用,但是我无法对输出使用某种替换。我还找到了一些可以使用setlocal enabledelayedexpansion
进行替换的东西,但是我不知道该如何使用通配符。
我的代码是:
@echo off
set "replace=localhost:.*"
set "replaced=localhost:80"
set "source=c:\blah\blah\streamstack.exe.config"
set "target=c:\blah\blah\streamstack1.exe.config"
setlocal enableDelayedExpansion
(
for /f "tokens=1* delims=:" %%a in ('findstr /N "^" %source%') do (
set "line=%%b"
if defined line set "line=!line:%replace%=%replaced%!"
echo(!line!
)
) > %target%
endlocal
我希望它能找到包含localhost:
的字符串,后跟代表端口的任何数字组,并替换为localhost:80
,这是我需要服务使用的端口。 / p>
答案 0 :(得分:0)
我决定走另一条路,并调用powershell,而不是尝试将所有这些工作都保存在bat文件中。
(Get-Content C:\Users\David\Desktop\streamstack.exe.config) | ForEach-Object { $_ -
replace "http://localhost:.*/", "http://localhost:80/" } | Set-Content
c:\blah\blah\streamstack.exe.config
这似乎可以完成工作,并且我可以使用...从蝙蝠内执行它。
powershell -executionPolicy bypass -noexit -file
答案 1 :(得分:0)
您尚未提供有关配置文件格式的任何详细信息。
假设每行有一个名称/值设置,并且行的顺序 无关紧要,那么有一个非常简单的批处理解决方案高效。使用FINDSTR将所有行 写入本地主机行,然后追加所需的本地主机行。
>"%target%" (findstr /v "^http://localhost:" "%source%" & echo http://localhost:80)
当然,如果行的顺序很重要,则上述方法将无效。
您应该查看我的JREPL.BAT regular expression find/replace utility。它非常强大,但易于使用。它是纯脚本(混合批处理/ JScript),可从XP开始在任何Windows计算机上运行。
使用与在PowerShell中使用的相同的查找/替换,JREPL解决方案将是
call jrepl "(http://localhost):.*" "$1:80" /f "%source%" /o "%target%"
我使用了一个正则表达式捕获组来节省一些打字。
JREPL有很多选项,并且该实用程序内置了完整的文档。使用jrepl /?help
获取所有可用帮助类型的描述。
答案 2 :(得分:0)
由于您尝试替换URL中的端口号,因此我对搜索字符串进行了一些扩展,以便在协议定义://
或http
之后以及之前添加前导https
主机名以及端口号后的/
(也符合your own answer)。
以下脚本仅在第一次出现所需的URL时替换端口号,这是在类似://
的字符串加上给定的主机名加上:
加上纯数字端口号加上遇到/
:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=c:\blah\blah\streamstack.exe.config" & rem // (original file)
set "_TARGET=c:\blah\blah\streamstack.exe.config" & rem // (modified file)
set "_TEMP=%TEMP%\%~n0_%RANDOM%.tmp" & rem // (temporary file)
set "_HOST=localhost" & rem // (host name)
set "_PORT=80" & rem // (new port name)
rem // Define to write to console if no target file is given:
if not defined _TARGET set "_TEMP=con"
rem // Store line-feed in variable:
(set ^"_LF=^
%= blank line =%
^")
rem // Write output to temporary file:
> "%_TEMP%" (
rem // Read source file line by line, precede each line by line number plus `:`:
for /F "delims=" %%L in ('findstr /N "^" "%_SOURCE%"') do (
rem // Store currently iterated line, reset buffer for part left to host name:
set "LINE=%%L" & set "LEFT="
rem // Toggle delayed expansion to avoid trouble with exclamation marks:
setlocal EnableDelayedExpansion
rem // Get line portion right to `://` + host name + `:`:
set "RIGHT=!LINE:*://%_HOST%:=!"
rem // Check whether host name part has really been found:
if not "!LINE!" == "!RIGHT!" (
rem /* Buffer right line portion in a `for` variable
rem to transport it over the `endlocal` barrier: */
for /F "delims=" %%J in (^""!RIGHT!"^") do (
rem // Replace `://` + host name + `:` by a line-feed:
for /F "delims=" %%I in (^"!LINE:://%_HOST%:^=^%_LF%%_LF%!^") do (
rem /* Ensure to only process first line of multi-line string
rem to get the line portion left to `://`+ host name + `:`: */
if not defined LEFT (
endlocal
rem /* Store line portion left to `://` + host name + `:`,
rem restore right line portion from `for` variable: */
set "LEFT=%%I" & set "RIGHT=%%~J"
rem /* Split off everything behind the first `/`, which
rem constitutes the port number: */
for /F "delims=/" %%F in ("0%%~J") do (
rem /* Check whether port number is purely numeric;
rem this is done by checking whether a `for /F` loop
rem iterates if numerals are defined as delimiters: */
for /F "delims=0123456789" %%E in ("%%F") do rem/
) && (
rem // `for /F` loop iterated, hence keep current line:
setlocal EnableDelayedExpansion
) || (
rem // `for /F` loop did not iterate, change port number:
setlocal EnableDelayedExpansion
set "LINE=!LEFT!://%_HOST%:%_PORT%/!RIGHT:*/=!"
)
)
)
)
)
rem // Return line string:
echo(!LINE:*:=!
endlocal
)
)
rem /* Move temporary file onto target file;
rem this allows source and target files to be identical: */
if defined _TARGET > nul move /Y "%_TEMP%" "%_TARGET%"
endlocal
exit /B