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

xzabzqsa  于 2023-01-05  发布在  Shell
关注(0)|答案(4)|浏览(158)

我想在空格上分割管道的每一行,然后将每个标记打印在它自己的行上。
我意识到我可以使用以下公式得到这个结果:

(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"}

很明显,它只打印第一个标记,有没有办法对标记进行for-each,依次打印每个标记?
还有,%{$data = $_.split(" "); Write-Output "$($data[0])"}部分我是从博客上得到的,我真的不明白我在做什么,也不知道语法是如何工作的。
我想用谷歌搜索一下,但我不知道该怎么称呼它。请帮我用一两个词搜索一下,或者给我一个链接,解释一下%和所有$符号的作用,以及左括号和右括号的意义。
我意识到我实际上不能使用(cat someFileInsteadOfAPipe).split(" "),因为文件(或者更可取的传入管道)包含多行。
关于一些答案:
如果在标记化之前使用Select-String过滤输出,则需要记住Select-String命令的输出不是字符串的集合,而是MatchInfo对象的集合。要获得要拆分的字符串,需要访问MatchInfo对象的Line属性,如下所示:

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

rjzwgtxy1#

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

关键字是$_,表示管道中的当前变量。
关于您在网上找到的代码:
%ForEach-Object的别名。括号内的任何内容都会在它接收到每个对象时运行一次。在本例中,它只运行一次,因为您发送给它的是单个字符串。
$_.Split(" ")正在获取当前变量并将其拆分为空格。当前变量将是ForEach当前正在循环的变量。

o8x7eapl

o8x7eapl2#

要补充Justus Grunow's helpful answer

  • 正如Joey在评论中指出的,PowerShell有一个强大的、基于正则表达式的-splitoperator
    *在其 * 一元 * 形式(-split '...')中,-split的行为类似于awk的默认字段拆分,这意味着:
  • 忽略前导和尾随空格。
  • 任何 * 连续 * 的空格(例如,* 多个 * 相邻空格)都被视为 * 单个 * 分隔符。
  • 在**PowerShell v4+**中,ForEach-Objectcmdlet的基于表达式(因此速度更快)替代方案可用:固有的.ForEach()方法,(与.Where()方法并列,Where-Object的一个更强大的、基于表达式的替代方法)。

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

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

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

vs91vp4v

vs91vp4v3#

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

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

Once

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

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

a
2cmtqfgy

2cmtqfgy4#

另一种方法是将Justus Thane和mklement0的答案结合起来,当你看到一个单行示例时,这样做没有意义,但当你试图批量编辑一个文件或一组文件名时,这样做就非常方便了:

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

这将显示为:

One
for
the
money

相关问题