使用 PowerShell 拆分字符串,并对每个令牌执行一些操作



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

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

(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]

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

-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

最新更新