Powershell 清理包含域的巨大文本文件

Powershell 清理包含域的巨大文本文件,powershell,grep,powershell-2.0,powershell-3.0,Powershell,Grep,Powershell 2.0,Powershell 3.0,我有一个数据库,其中包含以下事项中列出的域日志: .youtube.com .ziprecruiter.com 0.etsystatic.com 0.sparkpost.com 00.mail.ne1.yahoo.com 00072e01.pphosted.com 00111b01.pphosted.com 001d4f01.pphosted.com 011.mail.bf1.yahoo.com 1.amazonaws.com 我该如何使用powershell或grep来清理它们,尽管我更喜欢

我有一个数据库,其中包含以下事项中列出的域日志:

.youtube.com
.ziprecruiter.com
0.etsystatic.com
0.sparkpost.com
00.mail.ne1.yahoo.com
00072e01.pphosted.com
00111b01.pphosted.com
001d4f01.pphosted.com
011.mail.bf1.yahoo.com
1.amazonaws.com
我该如何使用powershell或grep来清理它们,尽管我更喜欢使用powershell,以便它们只包含扩展名为.com的根域,并删除任何单词和。在那之前

我认为最好的方法是查询,从右到左查找点,然后删除第二个点和它后面的任何东西。例如1.amazonaws.com,这里我们删除右边的第二个点以及它后面的内容? i、 e

您可以使用String.Trim方法清除前导点和尾随点,然后使用regex-replace操作符删除除顶级和二级域名以外的所有内容:

$strings = Get-Content database_export.txt

@($strings |ForEach-Object Trim '.') -replace '.*?(\w+\.\w+)$','$1' |Sort-Object -Unique

您可以将每一行读入一个字符串数组,使用,Split on。使用,使用[-2,-1]获取最后两项,然后使用重新加入数组。然后,我们可以使用-unique-from检索唯一项

或者使用Select Object-Last 2获取最后两项,然后通过管道发送到

输出:


这里还有另一种方法。[咧嘴笑]

它的作用

创建要使用的字符串数组 当准备好真正这样做时,删除整个region/endregion部分并使用Get Content加载文件。 遍历字符串的$InStuff集合 将当前项目拆分为点 获取结果数组中的最后两项 用一个点连接它们 将新字符串输出到$Results集合 在屏幕上显示 代码

#region >>> fake reading in a text file
#    in real life, use Get-Content
$InStuff = @'
.youtube.com
.ziprecruiter.com
0.etsystatic.com
0.sparkpost.com
00.mail.ne1.yahoo.com
00072e01.pphosted.com
00111b01.pphosted.com
001d4f01.pphosted.com
011.mail.bf1.yahoo.com
1.amazonaws.com
'@ -split [System.Environment]::NewLine
#endregion >>> fake reading in a text file

$Results = foreach ($IS_Item in $InStuff)
    {
    $IS_Item.Split('.')[-2, -1] -join '.'
    }

$Results
输出

youtube.com
ziprecruiter.com
etsystatic.com
sparkpost.com
yahoo.com
pphosted.com
pphosted.com
pphosted.com
yahoo.com
amazonaws.com
请注意,此代码要求字符串或多或少是有效的URL。我能想到以点结尾的无效的。。。而这些都将失败。如果需要处理此类问题,请添加所需的验证代码


另一个想法。。。如果文件很大[数以万计的字符串],您可能希望使用ForEach Object pipeline cmdlet[如RoadRunner所示]以牺牲速度来保存RAM

看起来你可以在点上分割,在结果数组中取最后两个项目,然后用一个点连接它们。[咧嘴笑]@Lee_Dailey-你应该提出这个作为回答;这就是路行者正在做的。@JeffZeitlin-是的,我似乎误判了这个想法的意义。哦,好吧。。。有人花了我不知道的时间。。。[grin]/////second thot,我的方法不同,似乎值得演示。谢谢你提醒我!我唯一肯定会在代码中更改的是使用双引号。有不少帖子认为最终的问题似乎是使用双引号,而单例可以避免意外的变量扩展。除非需要双引号,否则我尽量使用单引号。我已经更新了代码,只使用单引号。谢谢你的反馈:我的不好,它实际上是有效的:我忘了添加一个命令来保存它。谢谢。事实上,我知道一个终端点实际上可能是有效的,但它是无效的——也就是说,如果允许的话,example.com和example.com。它们被认为是等价的。如果您选择$IS_Item.Trim'..Split'.[-2,-1]-加入'.@JeffZeitlin-wow!我确信那是无效的。[咧嘴笑]但是,如果不处理这些代码,它会把代码吹到墙上。如果OP需要,我希望他/她询问。。。
Get-Content -Path .\database_export.txt | ForEach-Object {
    $_.Split('.') | Select-Object -Last 2 | Join-String -Separator '.'
} | Select-Object -Unique
youtube.com
ziprecruiter.com
etsystatic.com
sparkpost.com
yahoo.com
pphosted.com
amazonaws.com
#region >>> fake reading in a text file
#    in real life, use Get-Content
$InStuff = @'
.youtube.com
.ziprecruiter.com
0.etsystatic.com
0.sparkpost.com
00.mail.ne1.yahoo.com
00072e01.pphosted.com
00111b01.pphosted.com
001d4f01.pphosted.com
011.mail.bf1.yahoo.com
1.amazonaws.com
'@ -split [System.Environment]::NewLine
#endregion >>> fake reading in a text file

$Results = foreach ($IS_Item in $InStuff)
    {
    $IS_Item.Split('.')[-2, -1] -join '.'
    }

$Results
youtube.com
ziprecruiter.com
etsystatic.com
sparkpost.com
yahoo.com
pphosted.com
pphosted.com
pphosted.com
yahoo.com
amazonaws.com