我在powershell中有以下单行:
cat raw.txt | select-string -Pattern "\A[s]\w{1,12}\.\b" -AllMatches | % { $_.Matches } | % { $_.Value }
返回:
saltri.
swoptimusprime.
swdecepticons.
问题 如何删除点"。"来自我的主机名。
提前致谢
答案 0 :(得分:1)
PetSerAl,在对该问题的评论中,提供了关键指针:使用positive lookahead assertion ((?=...)
)来匹配输入的其他部分,而不在捕获的匹配中包含该部分强>
如果我们将此应用于您的解决方案并简化它,我们会得到:
Get-Content raw.txt | % { if ($_ -match '^s\w{1,12}(?=\.\b)') { $matches[0] } }
子表达式\.\b
- 文字.
后跟(非捕获)过渡到单词字符\b
- 匹配,但不是捕获;也就是说,$matches[0]
是包含字符串匹配部分的特殊$matches
变量的元素,不包含.
但是,由于我们之后使用-match
并访问特殊的$matches
变量,我们可以简化正则表达式中捕获组((...)
)的问题我们可以通过索引1
访问子字符串,因为它是正则表达式中的第一个(且唯一)捕获组:
Get-Content raw.txt | % { if ($_ -match '^(s\w{1,12})\.\b') { $matches[1] } }
有关您的解决方案尝试的说明(除了在匹配中包含.
):
您在没有切换Get-Content
的情况下使用-Raw
,这意味着输入行将通过管道单独发送:
\A
代替更熟悉的字符串/行首字母^
,因为这两者仅与多行不同输入。-AllMatches
选项毫无意义,因为根据定义,每行最多只能有 1 匹配。< / LI>
正如您所看到的,在这种情况下,只有%
ForEach-Object
个-match
块就足够了,简化了问题;在这种情况下,它都返回不需要的信息,并且性能优于Select-String
。
答案 1 :(得分:0)
由于我不知道你的文字是怎样的,所以对主机名进行分组应该足够了(通过-match
进行较短的尝试):
cat raw.txt | % {$_ -match "\A([s]\w{1,12})\.\b"; $matches[1] }