61

我想在空格上分割管道的每一行,然后在自己的行上打印每个标记。

我意识到我可以使用以下方法获得此结果:

(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对象的集合。要获取要拆分的字符串,您需要访问对象的Line属性MatchInfo,如下所示:

cat someFile | Select-String "keywordFoo" | %{$_.Line.Split(" ")}
4

4 回答 4

137
"Once upon a time there were three little pigs".Split(" ") | ForEach {
    "$_ is a token"
 }

关键是$_,它代表管道中的当前变量。

关于您在网上找到的代码:

%是 的别名ForEach-Object。括号内的任何内容都会针对它接收到的每个对象运行一次。在这种情况下,它只运行一次,因为您要向它发送一个字符串。

$_.Split(" ")正在获取当前变量并将其拆分为空格。当前变量将是当前正在循环的任何内容ForEach

于 2012-07-05T16:38:49.860 回答
3

为了补充Justus Thane 的有用答案

  • 正如Joey在评论中指出的那样,PowerShell 有一个强大的、基于正则表达式的-split 运算符

    • 形式 ( -split '...') 的-split行为类似于awk的默认字段拆分,这意味着:
      • 忽略前导和尾随空格。
      • 任何空格(例如,多个相邻空格)被视为单个分隔符。
  • PowerShell v4+中,可以使用基于表达式(因此速度更快)的cmdlet替代方案:数组(集合)方法ForEach-Object .ForEach(),如本博文中所述(与.Where()方法一起,是更强大的基于表达式的替代方法Where-Object)。

这是基于这些功能的解决方案:

PS> (-split '   One      for the money   ').ForEach({ "token: [$_]" })
token: [One]
token: [for]
token: [the]
token: [money]

请注意,前导和尾随空格被忽略,并且 和 之间的多个空格Onefor视为单个分隔符。

于 2018-05-04T14:15:25.697 回答
2

-split 输出一个数组,你可以将它保存到一个变量中,如下所示:

$a = -split 'Once  upon    a     time'
$a[0]

Once

另一个可爱的事情是,你可以在赋值语句的两边都有数组:

$a,$b,$c = -split 'Once  upon    a'
$c

a
于 2020-02-11T00:19:38.330 回答
1

实现这一点的另一种方法是结合 Justus Thane 和 mklement0 的答案。当您查看单行示例时,这样做没有意义,但是当您尝试批量编辑文件或一堆文件名时,它非常方便:

$test = '   One      for the money   '
$option = [System.StringSplitOptions]::RemoveEmptyEntries
$($test.split(' ',$option)).foreach{$_}

这将显示为:

One
for
the
money
于 2018-08-02T00:19:44.240 回答