13

我从 Java 应用程序(通过 Windows 命令提示符)中调用 PowerShell 来读取各种文件属性。

例如,

powershell (Get-Item 'C:\Users\erlpm\Desktop\Temp\s p a c e s.txt').creationTime

我用单引号将文件路径括起来,因为它可能包含空格。它工作得很好,直到我遇到一个包含方括号的文件路径,这似乎被解释为通配符。我设法通过添加-literalPath参数来解决它:

powershell (Get-Item -literalpath 'C:\Users\erlpm\Desktop\Temp\brackets[].txt').creationTime

到目前为止,一切都很好……但是文件路径也可能包含单引号、美元符号、和号等,并且所有这些字符似乎在 PowerShell 中都有特定的功能,而-literalPath参数似乎不起作用。

我尝试用双引号将路径括起来或用`字符转义,但这也没有解决我的问题:-(

关于如何将可能包含空格、单引号、方括号、& 符号、美元符号等的文件路径传递给 PowerShell 的任何建议?

这里有人已经向我展示了如何在 PowerShell 中使其工作,但不知何故,答案已被删除(?)。

无论如何,我确实创建了一个名为$ & ' [].txt. 这PowerShell 中有效(需要转义&):

Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"


    Directory: C:\Users\erlpm\Desktop\Temp


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2012-08-23     14:22          0 $ & ' [].txt

但是当我通过 Windows 命令提示符执行相同的 PowerShell 命令时,...

powershell Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"

...我收到此错误:

不允许使用与号。& 运算符保留供将来使用;使用“&”将 & 号作为字符串传递。
在行:1 字符:55 \

  • Get-Item -LiteralPath C:\Users\erlpm\Desktop\Temp`$ & <<<< ' [].txt \
    • CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException \
    • FullyQualifiedErrorId : & 不允许

使用-command参数并将 PowerShell 命令置于其间{}会给出完全相同的错误消息...

powershell -command {Get-Item -LiteralPath "C:\Users\erlpm\Desktop\Temp\`$ & ' [].txt"}
4

3 回答 3

10

那么这确实是一个关于cmd.exe字符串转义的问题。将 cmd 和 PowerShell 字符串转义结合起来简直就是一场噩梦。经过多次尝试,我得到了你的具体例子:

powershell.exe -nologo -noprofile -command ^&{ dir -LiteralPath ^"""".\`$ & ' [].txt"" }

    Directory: C:\Users\latkin
Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         8/23/2012   8:46 AM          0 $ & ' [].txt

完全直观,对吧?

您可以每次花 15 分钟与转义序列搏斗,或者您可以尝试一些其他方法。

将文件名放在一个文本文件中,然后从那里读出。

powershell.exe -command "&{dir -literal (gc .\filename.txt)  }"

或者

使用脚本

powershell.exe -file .\ProcessFiles.ps1  # In processfiles.ps1 you are in fully powershell environment, so escaping is easier

或者

使用 -EncodedCommand

请参阅powershell.exe -?(显示的最后一项)或http://dmitrysotnikov.wordpress.com/2011/07/06/passing-parameters-to-encodedcommand/

于 2012-08-23T16:08:38.347 回答
6

如果您可以将路径写入临时 .txt 文件,则以下操作正常:

(Get-Item -literalpath (gc 'C:\Temp\path.txt')).creationTime

文件@ C:\Temp\path.txt 包含带有特殊字符的路径,除此之外,我认为您必须在每个路径的基础上转义每个特殊字符。

除了上面的 hack 之外,PowerShell V3 似乎可以通过添加一个新的“魔术参数”语言功能来帮助解决这个问题。具体来说,请参阅此处标题为“更轻松地从 Cmd.exe 重用命令行”的部分,因为我讨厌链接腐烂,所以在下面无耻地转载了它:

从 Cmd.exe 更容易重用命令行

网络上到处都是为 Cmd.exe 编写的命令行。这些命令行在 PowerShell 中经常工作,但是当它们包含某些字符时,例如分号 (;)、美元符号 ($) 或花括号,您必须进行一些更改,可能会添加一些引号。这似乎是许多轻微头痛的根源。

为了帮助解决这种情况,我们添加了一种“逃避”命令行解析的新方法。如果您使用魔术参数 --%,我们将停止对您的命令行的正常解析并切换到更简单的东西。我们不匹配引号。我们不止于分号。我们不扩展 PowerShell 变量。如果您使用 Cmd.exe 语法(例如 %TEMP%),我们会扩展环境变量。除此之外,直到行尾的参数(或管道,如果您是管道)按原样传递。这是一个例子:

 echoargs.exe --% %USERNAME%,this=$something{weird}
 Arg 0 is <jason,this=$something{weird}>
于 2012-08-23T15:08:19.333 回答
6

该线程已有 5 年历史,因此时代可能已经改变,但对我有用的当前答案是使用反引号 (`) 符号来转义特殊字符。

在我的情况下,这是一个失败的目录路径中的美元符号。通过在美元符号前加一个反引号,一切正常。

前:

$dir = "C:\folder$name\dir"  # failed

后:

$dir = "C:\folder`$name\dir" # succeeded
于 2017-05-05T23:27:32.473 回答