在PowerShell中拆分,选择,加入
本文关键字:选择 加入 拆分 PowerShell | 更新日期: 2023-09-27 18:31:59
PowerShell中的以下C#(伪)代码的等效项是什么?
string str = "abc def ghi";
str = str.Split(" ").Select(s => "'"" + MakeRootedPath(s) + "'"").Join(" ");
// Result:
str == @"""C:'root'abc"" ""C:'root'def"" ""C:'root'ghi""";
它在空格处拆分字符串,转换每个标记并将其放入引号中,然后将标记与空格重新组合。
我在想这样的事情:
$str = $str -Split " " | Select-Object "`"" + (MakeRootedPath $_) + "`"" | -Join " "
但这主要是由我到处发现的碎片组成的,我很确定它不会像这样工作。我知道我可以用.NET的方式做,写很多行[string].Join
等等,但我正在寻找一个优雅的PowerShell解决方案。我知道它存在,但学习语法很复杂。
PS:这是完整性的MakeRootedPath
函数。
# Returns a rooted path. Non-rooted paths are interpreted relative to $rootDir.
#
function MakeRootedPath($path)
{
if (![System.IO.Path]::IsPathRooted($path))
{
return "$rootDir'$path"
}
return $path
}
String.Split()
方法可以像在 C# 中一样使用:
PS> $str = "abc def ghi"
PS> $str.Split(" ")
abc
def
ghi
Select()
和Join()
扩展方法不可用,但你可以使用 PowerShell 特定的ForEach()
方法和-join
运算符:
$str.Split(" ").ForEach({"""$(MakeRootedPath $_)"""}) -join " "
PowerShell 4.0 中引入了ForEach()
扩展方法 - 在旧版本中,必须使用 foreach(){}
循环:
(foreach($s in $str.Split(" ")){"""$(MakeRootedPath $_)"""}) -join " "
或管道连接到ForEach-Object
cmdlet:
($str.Split(" ")|ForEach-Object{"""$(MakeRootedPath $_)"""}) -join " "
# Suppose you have MakeRootedPath somewhere that does something usefull
# I provide a stub here so it is runnable in a console
function MakeRootedpath {"C:'$args"}
# option 1, use foreach-object
('abc def ghi' -split ' ' | foreach-object { "`"$(MakeRootedPath $_ )`""}) -join ' '
# option 2, use select-object (two times, as you need to expand property)
('abc def ghi' -split ' ' | select-object @{N='Item';E={"`"$(MakeRootedPath $_ )`" "}} |
Select -ExpandProperty Item) -join ' '
如果你MakeRootedPath()
所做的只是返回一个绝对路径,请使用带有适当参数的Join-Path
。这样
$s = "abc def ghi"
$r = "c:'root"
$o = $s -split " " | % { join-path $r $_ }
# Check output for single result
$o[1]
c:'root'def
# Print the whole array
$o
c:'root'abc
c:'root'def
c:'root'ghi
至于添加的逻辑,让我们使用 .Net 方法来检查绝对路径。例如,可以使用正则表达式来测试输入。既然已经有库方法,为什么还要费心重新发明轮子呢?
function RootedPath($s, $rootPath) {
if(-not [System.IO.Path]::IsPathRooted($s)) {
return join-path $rootPath $s
} else { return $s }
}
$s = "abc d:'def ghi" # NB: 2nd value is absolute path
$o = $s -split ' ' | % { RootedPath $_ "c:'myRoot" }
# Let's generate a fancy output
$p = '"' + $($o -join '" "') + '"'
$p # print output
"c:'myRoot'abc" "d:'def" "c:'myRoot'ghi"