首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用perl或*nix命令有效地对ip地址进行排序并合并两个文件?

如何使用perl或*nix命令有效地对ip地址进行排序并合并两个文件?
EN

Stack Overflow用户
提问于 2010-12-30 01:02:23
回答 1查看 1.5K关注 0票数 0

(*)这个问题应该在perl或任何*nix命令中完成。

我正在开发一个程序,efficiency matters.The file1由ip地址和其他一些数据组成:

代码语言:javascript
复制
index ipsrc     portsrc  ip dest     port src
8 128.3.45.10 2122 169.182.111.161 80 (same ip src and dst)
9 128.3.45.10 2123 169.182.111.161 22 (same ip src and dst)
10 128.3.45.10 2124 169.182.111.161 80 (same ip src and dst)
19 128.3.45.128 62256 207.245.43.126 80

和其他file2类似(file1和file2的顺序不同)

代码语言:javascript
复制
128.3.45.10 ioc-sea-lm 169.182.111.161 microsoft-ds 0 0 3 186 3 186 
128.3.45.10 hypercube-lm 169.182.111.161 https 0 0 3 186 3 186
128.3.44.112 pay-per-view 148.184.171.6 netbios-ssn 0 0 3 186 3 186
128.3.45.12 cadabra-lm 148.184.171.6 microsoft-ds 0 0 3 186 3 186

1-在第二列中使用IP地址对file1排序,在第一列中使用IP地址对file2排序

2-将File1的第1、3和5列与文件2合并

我需要创建一个新文件,它将如下所示:

代码语言:javascript
复制
128.3.45.10 ioc-sea-lm 169.182.111.161 microsoft-ds 0 0 3 186 3 186 --> 2122 80 8
128.3.45.10 hypercube-lm 169.182.111.161 https 0 0 3 186 3 186 --> 2123 22 9
128.3.44.112 pay-per-view 148.184.171.6 netbios-ssn 0 0 3 186 3 186 --> * * *
128.3.45.12 cadabra-lm 148.184.171.6 microsoft-ds 0 0 3 186 3 186 --> * * *

基本上会添加端口号和索引号。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-12-30 09:55:09

从表面上看,它似乎是sortjoin的一个显而易见的应用程序

代码语言:javascript
复制
sort -k2 file1 > sorted.1
sort -k1 file2 > sorted.2
join -1 2 -2 1 -a 2 -e '*' \
    -o 2.1,2.2,2.3,2.4,2.5,2.6,2.7,2.8,2.9,2.10,1.1,1.3,1.5 \
    sorted.1 sorted.2

然而,它的输出是:

代码语言:javascript
复制
128.3.44.112 pay-per-view 148.184.171.6 netbios-ssn 0 0 3 186 3 186 * * *
128.3.45.10 hypercube-lm 169.182.111.161 https 0 0 3 186 3 186 8 2122 80
128.3.45.10 ioc-sea-lm 169.182.111.161 microsoft-ds 0 0 3 186 3 186 8 2122 80
128.3.45.10 hypercube-lm 169.182.111.161 https 0 0 3 186 3 186 9 2123 22
128.3.45.10 ioc-sea-lm 169.182.111.161 microsoft-ds 0 0 3 186 3 186 9 2123 22
128.3.45.10 hypercube-lm 169.182.111.161 https 0 0 3 186 3 186 10 2124 80
128.3.45.10 ioc-sea-lm 169.182.111.161 microsoft-ds 0 0 3 186 3 186 10 2124 80
128.3.45.12 cadabra-lm 148.184.171.6 microsoft-ds 0 0 3 186 3 186 * * *

接近,但没有骰子:问题是IP地址128.3.45.10在file1中出现了三次,在file2和join中出现了两次,因此创建了6行(笛卡尔乘积)。

这似乎是一个需要在使用条目时使用/销毁条目的应用程序。这表明我们将需要使用Perl (或类似的脚本语言)。因此,我们不清楚是否需要对file1进行排序;我们需要读取file1并创建一个结构,其中关键字指向一个字符串数组,每个记录只包含所需的三个字段(1,3,5)。

然后,我们按顺序处理file2,在散列中找到匹配的IP地址,并使用数组中的第一个条目-如果没有这样的条目,则使用星号。我们也可以添加问题中要求的'-->‘。

这导致了一个相当简单的程序:

代码语言:javascript
复制
#!/usr/bin/env perl

use strict;
use warnings;

my %file1 = read_file1("file1");

sub read_file1
{
    my($file) = @_;
    open my $fh, '<', $file or die "Failed to open $file for reading ($!)";
    my %file1;
    while (my $line = <$fh>)
    {
        my @fields = split / /, $line;
        my $ip = $fields[1];
        $file1{$ip} = [ ] unless defined $file1{$ip};
        push @{$file1{$ip}}, "$fields[0] $fields[2] $fields[4]";
    }
    return %file1;
}

my $file2 = "file2";
open my $f2, '<', $file2 or die "Failed to open $file2 for reading ($!)";

while (my $line = <$f2>)
{
    chomp $line;
    my($ip) = ($line =~ m/^(\S+) /);
    my $aux = "* * *";
    if (defined $file1{$ip})
    {
        $aux = shift @{$file1{$ip}};
        delete $file1{$ip} if scalar @{$file1{$ip}} == 0;
    }
    print "$line --> $aux\n";
}

输出是这样的--完全按照请求:

代码语言:javascript
复制
128.3.45.10 ioc-sea-lm 169.182.111.161 microsoft-ds 0 0 3 186 3 186  --> 8 2122 80
128.3.45.10 hypercube-lm 169.182.111.161 https 0 0 3 186 3 186 --> 9 2123 22
128.3.44.112 pay-per-view 148.184.171.6 netbios-ssn 0 0 3 186 3 186 --> * * *
128.3.45.12 cadabra-lm 148.184.171.6 microsoft-ds 0 0 3 186 3 186 --> * * *

看不到一种类型--所以它是相当有效的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4556076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档