【问题标题】:Batch file passing filenames with apostrophes to powershell command将带有撇号的文件名的批处理文件传递给powershell命令
【发布时间】:2021-06-17 04:52:28
【问题描述】:

我在将文件名从批处理传递到 powershell 命令时遇到问题。我需要更改当前目录的子目录中所有文件的编码。有些文件名包含撇号,我宁愿保持原样。

这是我第一次尝试代码:

for /R "%cd%\Legacy .xml files\" %%f in (*.xml) do (
    echo. file: %%~nxf
    set filename=%%~nxf
    powershell -Command "& {Get-Content '%%f' | Set-Content -Encoding utf8 '%cd%\XML converted to UTF-8\!filename!';}"
)

这对于名称中带有撇号的文件会出现此错误,例如D'Este.xml(注意 - 有几个文件带有撇号):

Get-Content : A positional parameter cannot be found that accepts argument 'Este.xml | Set-Content -Encoding utf8
C:\Users\pwessels\Documents\Report'.
At line:1 char:4
+ & {Get-Content 'C:\Users\pwessels\Documents\Report tinkering\Ops-Dail ...
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Content], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetContentCommand

然后我尝试在 powershell 命令中转义双引号而不是单引号,但我收到不同的错误(这次在每个文件上)。

for /R "%cd%\Legacy .xml files\" %%f in (*.xml) do (
    echo. file: %%~nxf
    set filename=%%~nxf
    powershell -Command "& {Get-Content ""%%f"" | Set-Content -Encoding utf8 ""%cd%\XML converted to UTF-8\!filename!"";}"
)

这给出了这个错误:

The string is missing the terminator: ".
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

寻找有关如何完成此任务的任何见解!

编辑: Powershell 尝试也不起作用 - 我完全没有使用 powershell 的经验,而且我遇到了一个找不到解决方案的 Set-ExecutionPolicy 错误。

Get-ChildItem "$PSScriptRoot\Legacy .xml files" -Filter *.xml | 
Foreach-Object {
    $content = Get-Content $_.FullName

    #filter and save content to the original file
    $content | Set-Content -Encoding utf8 "$($PSScriptRoot)\XML converted to UTF-8\$($_.ShortName).xml"
}
Read-Host -Prompt "Press Enter to exit"

错误:

Set-ExecutionPolicy : Windows PowerShell updated your execution policy successfully, but the setting is overridden by
a policy defined at a more specific scope.  Due to the override, your shell will retain its current effective
execution policy of RemoteSigned. Type "Get-ExecutionPolicy -List" to view your execution policy settings. For more
information please see "Get-Help Set-ExecutionPolicy".
At line:1 char:46
+ ...  -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & 'C ...
+                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (:) [Set-ExecutionPolicy], SecurityException
    + FullyQualifiedErrorId : ExecutionPolicyOverride,Microsoft.PowerShell.Commands.SetExecutionPolicyCommand

【问题讨论】:

  • @aschipfl 刚刚尝试添加set filename=!filename:'=``'!,不幸的是它不起作用。
  • 您在该 BAT 脚本中显示的所有内容都可以完全在 PoSh 中完成。所以......为什么不在powershell中做这一切呢?
  • @Lee_Dailey 批处理文件中的内容比这更多 - 而且我更喜欢批处理文件而不是 powershell 脚本,所以它们就是我想要的。
  • [1] 您应该不需要设置执行策略。 [2] 在您的脚本中设置该设置不会为该脚本更改它 - 它仅适用于以后的会话。 [3] 您的错误文本显示的代码不在您发布的 PoSh 脚本中……那么该代码来自哪里?

标签: powershell batch-file


【解决方案1】:

我在编写的 DOS 脚本中遇到了同样的问题。我的解决方案在以下代码片段中。它来自一个调用 PowerShell 脚本的 DOS 脚本,Remove-ItemSafely 通过将 tmp 文件移动到回收站来“删除”它们。如果当前目录中的任何文件名是撇号,则在调用 PowerShell 命令之前将其替换为临时变量中的两个撇号。

setlocal EnableDelayedExpansion
for /r %%f in (*.tmp) do (
   
    echo.
    echo original filename %%f
    set "c_tmp=%%f" & set "c_tmp=!c_tmp:'=''!"

    echo modified filename !c_tmp!
    echo powershell.exe -command "& Remove-ItemSafely '!c_tmp!'"
         powershell.exe -command "& Remove-ItemSafely '!c_tmp!'"
)

当然,您可以根据需要调整代码。只需使用!c_tmp! 作为修改后的文件名。

【讨论】:

    猜你喜欢
    • 2012-11-26
    • 2023-01-23
    • 2015-03-22
    • 1970-01-01
    • 2018-06-20
    • 2020-09-10
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多