我有一个包含以下内容的文本文件:
#define VERSION "0.1.2"
我需要从正在运行的批处理文件中替换该版本号。
set NEW_VERSION="0.2.0"
powershell -Command "(gc BBB.iss) -replace '#define VERSION ', '#define VERSION %NEW_VERSION% ' | Out-File BBB.iss"
我知道我的比赛模式不正确。我需要选择整行,包括“0.2.0”,但我无法弄清楚如何逃避所有这一切,因为它全部用双引号括起来,所以它在批处理文件中运行。
我猜[0-9]。[0-9]。[0-9]会匹配实际的旧版本号,但报价呢?
答案 0 :(得分:0)
但报价呢?
使用cmd.exe
从powershell -command "...."
(批处理文件)调用PowerShell的CLI时,使用\"
传递 embedded "
(这可能会令人惊讶,因为PowerShell- 内部您通常在`"
内使用""
或"..."
,但这是安全的选择从外面。 [1] 。)
这是匹配并替换"..."
之后#define VERSION
之后的所有内容的方法:
:: Define the new version *without* double quotes
set NEW_VERSION=0.2.0
powershell -Command "(gc BBB.iss) -replace '(?<=#define VERSION\s+\").+?(?=\")', '%NEW_VERSION%' | Set-Content -Encoding ascii BBB.iss"
请注意,使用Out-File
(在问题中使用)来重写文件会创建一个UTF-16LE(&#34; Unicode&#34;)编码文件,这可能是不受欢迎的;使用Set-Content -Encoding ...
来控制输出编码。以上命令以Set-Content -Encoding ascii
为例
另请注意,如果写入文件被中断,以这种方式重写现有文件(将现有内容读入内存,将修改后的内容写回)会带来轻微的数据丢失风险。
(?<=#define VERSION\s+\")
是背后的断言((?<=...)
),它与文字#define VERSION
匹配,后跟至少一个空格或制表符{{{ 1}})和文字\s+
"
如何转义为"
,令人惊讶的是,您需要如何转义文字 \"
字符。从"
(批处理文件)向PowerShell传递命令时。 [1] cmd.exe
然后非贪婪地(.+?
)匹配一个或多个(?
)个字符(+
)......
...在通过.
找到结束"
(转发为\"
)之前,先看看提前断言
(?=\")
)
净效果是只有 ((?<=...)
之间的字符匹配 - 即仅仅是版本号 - 然后允许将其替换为 > "..."
,新版本号。
更简单的替代方案,如果只需要替换第一行,而无需保留其中的特定信息:
'%NEW_VERSION%'
该命令只是从新的第1行和(powershell -nop -Command "@('#define VERSION \"%NEW_VERSION%\"') + (gc BBB.iss | Select -Skip 1) | Set-Content -Encoding ascii BBB.iss"
)创建一个输出行的数组(@(...)
),除了现有文件的第1行(+
)之外回到档案。
[1]从gc ... | Select-Object -Skip 1
致电时,将嵌入式cmd.exe
转发为"
有时,但并非始终有效(请尝试>
""
)。
相反,powershell -Command "'Nat ""King"" Cole'"
- 逃避是安全的选择
\"
,这是`"
内"
的典型PowerShell- 内部方法,从1>调用{{1} }}
答案 1 :(得分:-1)
你可以试试这个,
powershell -Command "(gc BBB.iss) -replace '(?m)^\s*#define VERSION .*$', '#define VERSION %NEW_VERSION% ' | Out-File BBB.iss"
如果你想留下双引号,
powershell -Command "(gc BBB.iss) -replace '(?m)^\s*#define VERSION .*$', '#define VERSION "%NEW_VERSION%"' | Out-File BBB.iss"