使用 PowerShell 拆分字符串并对每个令牌执行一些操作
Posted
技术标签:
【中文标题】使用 PowerShell 拆分字符串并对每个令牌执行一些操作【英文标题】:Split string with PowerShell and do something with each token 【发布时间】:2012-07-06 02:29:48 【问题描述】:我想在空格上分割管道的每一行,然后在自己的行上打印每个标记。
我意识到我可以使用以下方法得到这个结果:
(cat someFileInsteadOfAPipe).split(" ")
但我想要更多的灵活性。我希望能够对每个令牌做任何事情。 (我曾经在 Unix 上使用 AWK,我正在尝试获得相同的功能。)
我目前有:
echo "Once upon a time there were three little pigs" | %$data = $_.split(" "); Write-Output "$($data[0]) and whatever I want to output with it"
显然,它只打印第一个标记。有没有办法让我在令牌上逐个打印,依次打印?
另外,%$data = $_.split(" "); Write-Output "$($data[0])"
部分是我从博客中得到的,我真的不明白我在做什么或语法是如何工作的。
我想用谷歌搜索它,但我不知道该怎么称呼它。请帮我说一两个词给 Google,或者一个链接向我解释 %
和所有 $
符号的作用,以及左括号和右括号的意义。
我意识到我实际上不能使用(cat someFileInsteadOfAPipe).split(" ")
,因为文件(或最好的传入管道)包含多行。
关于一些答案:
如果您在标记化之前使用Select-String
过滤输出,您需要记住Select-String
命令的输出不是字符串集合,而是MatchInfo
对象的集合。要获取要拆分的字符串,您需要访问MatchInfo
对象的Line
属性,如下所示:
cat someFile | Select-String "keywordFoo" | %$_.Line.Split(" ")
【问题讨论】:
【参考方案1】:"Once upon a time there were three little pigs".Split(" ") | ForEach
"$_ is a token"
key是$_
,代表管道中的当前变量。
关于你在网上找到的代码:
%
是ForEach-Object
的别名。括号内的任何内容都会针对它接收到的每个对象运行一次。在这种情况下,它只运行一次,因为您要向它发送一个字符串。
$_.Split(" ")
正在获取当前变量并将其拆分为空格。当前变量将是 ForEach
当前正在循环的任何内容。
【讨论】:
啊啊,感谢您的编辑。知道%
是 foreach-object
的缩写意味着我可以对多行执行此操作:cat .\tmp.txt | %$_.Split(" ") | %Write-Output "$($_) hello"
问题已解决。
完美!很高兴我能帮助你。您的命令的最后一部分实际上可能只是"$_ hello"
。如果您尝试在字符串中扩展对象属性的值,则只需要使用 $($variable) 表示法。例如"My last name is $($person.surname)."
或 cmdlet 方法的输出:"Tomorrow's date is $((Get-Date).AddDays(1))"
。
请注意:从 PowerShell v2 开始,有一个 -split
运算符可用于在一般空格 (-split $foo
) 上拆分,或类似于 .Split(' ')
: $foo -split ' '
。
【参考方案2】:
补充Justus Thane's helpful answer:
正如Joey 在评论中指出的那样,PowerShell 有一个强大的、基于正则表达式的-split
operator。
-split '...'
) 中,-split
的行为类似于 awk
的默认字段拆分,这意味着:
忽略前导和尾随空格。
任何运行个空格(例如,多个相邻空格)都被视为单个分隔符。
在 PowerShell v4+ 中,可以使用基于表达式的 - 因此更快 - ForEach-Object
的替代品cmdlet:.ForEach()
数组(collection) 方法,如this blog post 中所述(与.Where()
方法一起,是Where-Object
的更强大、基于表达式的替代方法)。
以下是基于这些功能的解决方案:
PS> (-split ' One for the money ').ForEach( "token: [$_]" )
token: [One]
token: [for]
token: [the]
token: [money]
请注意,前导和尾随空格被忽略,One
和 for
之间的多个空格被视为单个分隔符。
【讨论】:
【参考方案3】:-split 输出一个数组,你可以像这样将它保存到一个变量中:
$a = -split 'Once upon a time'
$a[0]
Once
另一个可爱的东西,你可以在赋值语句的两边都有数组:
$a,$b,$c = -split 'Once upon a'
$c
a
【讨论】:
【参考方案4】:实现此目的的另一种方法是结合 Justus Thane 和 mklement0 的答案。当您查看单行示例时,这样做没有意义,但是当您尝试批量编辑文件或一堆文件名时,它非常方便:
$test = ' One for the money '
$option = [System.StringSplitOptions]::RemoveEmptyEntries
$($test.split(' ',$option)).foreach$_
结果如下:
One
for
the
money
【讨论】:
我一直发现在使用纯文本文件时,我得到了错误的数字,其中一行包含一个计算机名称(主机名)和一个空行。$counterTotal = $($computers.Split(" ").count)
正是我想要的。感谢@s31064 的启发以上是关于使用 PowerShell 拆分字符串并对每个令牌执行一些操作的主要内容,如果未能解决你的问题,请参考以下文章
当内容在单引号中时,使用 PowerShell 将 SQL 文件/字符串拆分为批处理排除拆分
将 pandas df 中的句子拆分为多行单词并对每个句子进行编号
如何将字符串拆分为列表并在python中将两个已知令牌合并为一个?