我想在空格上拆分管道的每一行,然后在自己的行上打印每个标记。
我意识到我可以使用以下方法获得此结果:
(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])"}
部分,我真的不明白我在做什么或语法是如何工作的。
我想谷歌搜索它,但我不知道该怎么称呼它。请帮我用一两句话给谷歌,或者一个链接向我解释%
和所有$
符号的作用,以及左括号和右括号的重要性。
意识到我实际上不能使用(cat someFileInsteadOfAPipe).split(" ")
,因为文件(或更好的传入管道)包含多行。
关于一些答案:
如果在标记化之前使用 Select-String
筛选输出,则需要记住,Select-String
命令的输出不是字符串的集合,而是MatchInfo
对象的集合。要访问要拆分的字符串,您需要访问 MatchInfo
对象的 Line
属性,如下所示:
cat someFile | Select-String "keywordFoo" | %{$_.Line.Split(" ")}
"Once upon a time there were three little pigs".Split(" ") | ForEach {
"$_ is a token"
}
键是 $_
,它代表管道中的当前变量。
关于您在网上找到的代码:
%
是 ForEach-Object
的别名。括号内包含的任何内容都会针对它接收的每个对象运行一次。在这种情况下,它只运行一次,因为您要向它发送单个字符串。
$_.Split(" ")
正在获取当前变量并将其拆分为空间。当前变量将是当前由 ForEach
循环的任何变量。
为了补充Justus Grunow的有用答案:
-
正如Joey在评论中指出的那样,PowerShell有一个强大的,基于正则表达式的
-split
运算符。-
在一元形式(
-split '...'
)中,-split
的行为类似于awk
的默认字段拆分,这意味着:- 前导和尾随空格将被忽略。
- 任何空格(例如,多个相邻空格)都被视为单个分隔符。
-
在一元形式(
-
在 PowerShell v4+ 中,可以使用基于表达式(因此速度更快)替代
ForEach-Object
cmdlet:内部.ForEach()
方法(与.Where()
方法一起,是更强大、基于表达式的Where-Object
替代方法)。
下面是基于这些功能的解决方案:
PS> (-split ' One for the money ').ForEach({ "token: [$_]" })
token: [One]
token: [for]
token: [the]
token: [money]
请注意,前导和尾随空格被忽略,One
和for
之间的多个空格被视为单个分隔符。
-split 输出一个数组,您可以将其保存到如下所示的变量中:
$a = -split 'Once upon a time'
$a[0]
Once
另一个可爱的事情,你可以在赋值语句的两侧都有数组:
$a,$b,$c = -split 'Once upon a'
$c
a
实现此目的的另一种方法是结合 Justus Thane 和 mklement0 的答案。 当您查看单行示例时,这样做是没有意义的,但是当您尝试批量编辑文件或一堆文件名时,它会派上用场:
$test = ' One for the money '
$option = [System.StringSplitOptions]::RemoveEmptyEntries
$($test.split(' ',$option)).foreach{$_}
这将结果为:
One
for
the
money