Powershell,使用(space 分隔的)字符串作为程序的参数
Powershell, use (space-separated) string as arguments to a program
我已阅读 但它没有解决我的问题。
我有一个 space 分隔的字符串,比方说 $MyString = "arg1 arg2"
。假设我有一个名为 MyProgram
的命令行程序,它接受任意数量的位置参数,因此它可以像 MyProgram arg1 arg2
一样 运行。但是 MyProgram $MyString
不起作用,MyProgram ($MyString -split ' ')
和 MyProgram $($MyString -split ' ')
也不起作用。我得到同样的错误,基本上说它不识别参数“arg1 arg2”,我猜这是因为它仍然认为它是一个包含 space 的参数而不是两个参数。实际上,$MyString
可能非常大并且是从文件中读取的。我该怎么做?
哦,我刚刚发现如何大声笑。我早该想到这一点;基本上,只需使用 splatting 以下对我有用:
$MyArray = $($MyString -split " ")
MyProgram @MyArray
解释:第一行将字符串转换为由space(" ")分割的字符串数组;命令周围的 $(...)
符号捕获命令的输出,然后我将其分配给 $MyArray
。然后,我没有将 $MyArray
与美元符号 $
一起使用,而是将其与 @
一起使用,将字符串数组拼成 MyProgram
.
的参数
这些对我有用($args 已保留)。 -split 在左侧拆分为空白。或者您可以从文件中获取内容,其中每个参数都在单独的一行上。您可能 运行 限制了命令行的长度。将该列表通过管道传输或从文件中加载可能是更好的方法。
echo hi > file.txt
$args2 = 'hi','file.txt'
findstr $args2
# hi
$args2 = 'hi','file.txt'
& findstr $args2
# hi
$args2 = 'hi file.txt'
findstr (-split $args2)
# hi
findstr ($args2 -split ' ')
# hi
tl;dr
对于调用PowerShell命令你确实需要splatting才能通过 数组的元素 作为 个人,位置 参数 ;这需要在 辅助变量 中定义数组,然后可以使用 sigil @
代替 $
传递以请求展开:
$myArray = -split $myString # See below for limitations, bottom section for fix
MyPowerShellCommand @myArray # Array elements are passed as indiv. arguments.
虽然此技术也适用于 外部程序,但它并不是绝对必要的,您可以直接传一个数组达到同样的效果:
MyExternalProgram (-split $myString) # Array elements are passed as indiv. args.
请注意,(...)
而不是 $(...)
用于将表达式作为参数传递。 (...)
通常就足够了,通常更可取,因为 $(...)
可能有副作用 - 详情请参阅 。
只是为了把 and 放在一起:
首先,需要明确的是:由于仅按 空格 进行拆分,这两个答案都无法正确处理参数列表字符串中具有 嵌入空格的参数(因此,有必要使用 嵌入式引号 ),例如,$myString = "arg1 `"arg2 with spaces`" arg3"
不会按预期工作 - 请参阅底部的解决方案。
撇开这个不谈,区别是:
调用外部程序时,如链接post、传递一个数组导致每个元素成为它自己的参数.
- 也就是说,
myExternalProgram (-split $MyString)
可以。
- 请注意,我使用
-split
operator 的 一元 形式进行更灵活的标记化,它被 任何非空 运行 的空格 同时忽略前导和尾随空格(与 awk
的默认行为相同)。
当调用 PowerShell 命令 时, 数组由默认通过原样,作为一个整体,作为单个参数.
要达到与外部程序相同的效果,即 将数组的元素作为单独的位置参数传递,您确实必须使用 splatting,即您必须:
- 首先将数组保存在变量中:
$myArray = -split $myString
,
- 然后你可以通过使用
@
而不是 $
作为印记将其作为 splatted 参数传递: MyPowerShellCommand @myArray
请注意 在调用 PowerShell 命令时 它比 使用 hashtable- 而不是基于数组的展开 ,因为它 允许您通过名称 显式绑定到参数 而不是按位置 - PowerShell 命令通常具有可以仅 按名称绑定的参数。
- 例如,如果
MyPowerShellCommand
接受参数 -Foo
和 -Bar
,您可以使用:
$myArgs = @{ Foo='foo value'; Bar='bar value '}; MyPowerShellCommand @myArgs
如果您确实想要处理参数列表字符串,这些字符串的参数带有 嵌入式引号:
$myString = 'arg1 "arg2 with spaces" arg3'
$myArray = (Invoke-Expression ('Write-Output -- ' + $myString -replace '$', "`0")) -replace "`0", '$$'
注意:,但在这个特定命令中采取的额外预防措施使其使用安全。
$myArray
是一个包含逐字元素 arg1
、arg2 with spaces
和 arg3
的 3 元素数组,可以再次如上所示使用。
有关该技术的说明,请参阅 。
我已阅读
我有一个 space 分隔的字符串,比方说 $MyString = "arg1 arg2"
。假设我有一个名为 MyProgram
的命令行程序,它接受任意数量的位置参数,因此它可以像 MyProgram arg1 arg2
一样 运行。但是 MyProgram $MyString
不起作用,MyProgram ($MyString -split ' ')
和 MyProgram $($MyString -split ' ')
也不起作用。我得到同样的错误,基本上说它不识别参数“arg1 arg2”,我猜这是因为它仍然认为它是一个包含 space 的参数而不是两个参数。实际上,$MyString
可能非常大并且是从文件中读取的。我该怎么做?
哦,我刚刚发现如何大声笑。我早该想到这一点;基本上,只需使用 splatting 以下对我有用:
$MyArray = $($MyString -split " ")
MyProgram @MyArray
解释:第一行将字符串转换为由space(" ")分割的字符串数组;命令周围的 $(...)
符号捕获命令的输出,然后我将其分配给 $MyArray
。然后,我没有将 $MyArray
与美元符号 $
一起使用,而是将其与 @
一起使用,将字符串数组拼成 MyProgram
.
这些对我有用($args 已保留)。 -split 在左侧拆分为空白。或者您可以从文件中获取内容,其中每个参数都在单独的一行上。您可能 运行 限制了命令行的长度。将该列表通过管道传输或从文件中加载可能是更好的方法。
echo hi > file.txt
$args2 = 'hi','file.txt'
findstr $args2
# hi
$args2 = 'hi','file.txt'
& findstr $args2
# hi
$args2 = 'hi file.txt'
findstr (-split $args2)
# hi
findstr ($args2 -split ' ')
# hi
tl;dr
对于调用PowerShell命令你确实需要splatting才能通过 数组的元素 作为 个人,位置 参数 ;这需要在 辅助变量 中定义数组,然后可以使用 sigil @
代替 $
传递以请求展开:
$myArray = -split $myString # See below for limitations, bottom section for fix
MyPowerShellCommand @myArray # Array elements are passed as indiv. arguments.
虽然此技术也适用于 外部程序,但它并不是绝对必要的,您可以直接传一个数组达到同样的效果:
MyExternalProgram (-split $myString) # Array elements are passed as indiv. args.
请注意,(...)
而不是 $(...)
用于将表达式作为参数传递。 (...)
通常就足够了,通常更可取,因为 $(...)
可能有副作用 - 详情请参阅
只是为了把
首先,需要明确的是:由于仅按 空格 进行拆分,这两个答案都无法正确处理参数列表字符串中具有 嵌入空格的参数(因此,有必要使用 嵌入式引号 ),例如,$myString = "arg1 `"arg2 with spaces`" arg3"
不会按预期工作 - 请参阅底部的解决方案。
撇开这个不谈,区别是:
调用外部程序时,如链接post、传递一个数组导致每个元素成为它自己的参数.
- 也就是说,
myExternalProgram (-split $MyString)
可以。 - 请注意,我使用
-split
operator 的 一元 形式进行更灵活的标记化,它被 任何非空 运行 的空格 同时忽略前导和尾随空格(与awk
的默认行为相同)。
- 也就是说,
当调用 PowerShell 命令 时, 数组由默认通过原样,作为一个整体,作为单个参数.
要达到与外部程序相同的效果,即 将数组的元素作为单独的位置参数传递,您确实必须使用 splatting,即您必须:
- 首先将数组保存在变量中:
$myArray = -split $myString
, - 然后你可以通过使用
@
而不是$
作为印记将其作为 splatted 参数传递:MyPowerShellCommand @myArray
- 首先将数组保存在变量中:
请注意 在调用 PowerShell 命令时 它比 使用 hashtable- 而不是基于数组的展开 ,因为它 允许您通过名称 显式绑定到参数 而不是按位置 - PowerShell 命令通常具有可以仅 按名称绑定的参数。
- 例如,如果
MyPowerShellCommand
接受参数-Foo
和-Bar
,您可以使用:
$myArgs = @{ Foo='foo value'; Bar='bar value '}; MyPowerShellCommand @myArgs
- 例如,如果
如果您确实想要处理参数列表字符串,这些字符串的参数带有 嵌入式引号:
$myString = 'arg1 "arg2 with spaces" arg3'
$myArray = (Invoke-Expression ('Write-Output -- ' + $myString -replace '$', "`0")) -replace "`0", '$$'
注意:
$myArray
是一个包含逐字元素 arg1
、arg2 with spaces
和 arg3
的 3 元素数组,可以再次如上所示使用。
有关该技术的说明,请参阅