使用 Batch 和 Powershell 替换 txt 文件中的多个字符串

Replace multiple strings in txt file using Batch and Powershell

我构建了一个运行 BTEQ 脚本的批处理文件,returns 将数据保存在一个 txt 文件中。但是,我正在扩展我的代码以允许用户输入 user_id、密码和句点参数 YYYYMM。 我最初将我的个人登录信息硬编码到 BTEQ 文件中,并像这样仅使用快照参数进行测试。

echo off
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
SET /P SNAPSHOT="What snapshot should I use [YYYYMM]?"
DEL EXPORT.TXT
POWERSHELL -COMMAND "(GET-CONTENT TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE \"\?YYYYMM\"", %SNAPSHOT% "} | OUT-FILE TEST.TXT";
bteq < test.txt > output.txt 2>&1
POWERSHELL -COMMAND "(GET-CONTENT TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE " %SNAPSHOT% ,"\"?YYYYMM\"} | OUT-FILE TEST.TXT";
@echo off goto end
en @echo exit

代码按预期运行。但是,当我去添加用户 ID 和密码时,我只是复制了 PowerShell 的快照代码并根据需要替换了变量。

echo off
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
SET /P USER_ID=Enter User ID:
SET /P USER_PASSWORD=Enter Password:
SET /P SNAPSHOT="What snapshot should I use [YYYYMM]?"
DEL EXPORT.TXT
POWERSHELL -COMMAND "(GET-CONTENT TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE \"$USER_ID\"", %USER_ID% "} | OUT-FILE TEST.TXT";
POWERSHELL -COMMAND "(GET-CONTENT TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE \"$USERPASSWORD\"", %USER_PASSWORD% "} | OUT-FILE TEST.TXT"; 
POWERSHELL -COMMAND "(GET-CONTENT TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE \"\?YYYYMM\"", %SNAPSHOT% "} | OUT-FILE TEST.TXT";
bteq < test.txt > output.txt 2>&1
::POWERSHELL -COMMAND "(GET-CONTENT TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE " %SNAPSHOT% ,"\"?YYYYMM\"} | OUT-FILE TEST.TXT";
@echo off goto end
en @echo exit

快照代码仍然有效,但我收到 User_ID 和 User_Password 用户输入的错误。如下:

Enter User ID:userTest
Enter Password:TestPass
What snapshot should I use [YYYYMM]?202102

At line:1 char:66
+ ... -CONTENT TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE "$USER_ID", userTes ...
+                                                                  ~
Missing expression after ','.
At line:1 char:67
+ ... TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE "$USER_ID", userTest } | OUT ...
+                                                          ~~~~~~~~
Unexpected token 'userTest' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingExpressionAfterToken

At line:1 char:71
+ ... ENT TEST.TXT) | FOREACH-OBJECT {$_ -REPLACE "$USERPASSWORD", TestPas ...
+                                                                  ~
Missing expression after ','.
At line:1 char:72
+ ... TXT) | FOREACH-OBJECT {$_ -REPLACE "$USERPASSWORD", TestPass } | OUT ...
+                                                          ~~~~~~~~
Unexpected token 'TestPass' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : MissingExpressionAfterToken

这是我的建议,使用我评论中建议的语法,但不是多个 PowerShell 实例,而是一个:

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Get-Content -Path \".\test.txt\") | ForEach-Object { $_.Replace(\"`$USER_ID\", \"%USER_ID%\").Replace(\"`$USERPASSWORD\", \"%USER_PASSWORD%\").Replace(\"?YYYYMM\", \"%SNAPSHOT%\") } | Set-Content -Path \".\test.txt\""

如果您更喜欢在 PowerShell 中使用单引号(在这种情况下更易于阅读和理解),则:

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Get-Content -Path '.\test.txt') | ForEach-Object { $_.Replace('$USER_ID', '%USER_ID%').Replace('$USERPASSWORD', '%USER_PASSWORD%').Replace('?YYYYMM', '%SNAPSHOT%') } | Set-Content -Path '.\test.txt'"

这些示例基于我对您的代码应该在 test.txt 中替换的内容的解释,即文字字符串 $USER_ID$USERPASSWORD?YYYYMM

要return将%SNAPSHOT%的字符串值返回到文字字符串?YYYYMM,在运行你的bteq命令之后,(正如您在代码中所使用的那样),那么您可以使用:

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Get-Content -Path \".\test.txt\") | ForEach-Object { $_.Replace(\"%SNAPSHOT%\", \"?YYYYMM\") } | Set-Content -Path \".\test.txt\""

或者

%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(Get-Content -Path '.\test.txt') | ForEach-Object { $_.Replace('%SNAPSHOT%', '?YYYYMM') } | Set-Content -Path '.\test.txt'"

如果您要 return 所有三个字符串,而不仅仅是一个字符串,那么您可以只使用您选择的第一个示例,并交换每个字符串对的位置。但是,为此,我对我来说似乎更简单,只需 Set-Conent 到一个新文件,使用它,然后删除,而不是继续修改同一个文件。