2

问题是:我有不同的 txt 文件,其中为到达服务器的每个恶意软件数据包注册了时间戳和 IP 地址。我想要做的是创建另一个 txt 文件,该文件显示,对于每个 ip,恶意软件数据包第一次到达。

一般来说,我想做这样的事情:

for every  line in file.txt
 if (ip is not present in list.txt)
 copy timestamp and ip in list.txt

我正在使用 awk 来做这件事。主要问题是“如果 ip 不在 list.txt 中”。我正在这样做:

 {    a=$( grep -w "$3" list.txt | wc -c );
    if ( a == 0 )
   {
     #copy timestamp and ip in list.txt
   }

(我使用 $3 因为 IP 地址在源文件的第三列)

我不知道如何让 awk 评估 grep 函数。我也尝试过使用反引号,但它没有用。有人可以给我一些提示吗?

我正在像这样的测试文件上测试我的脚本:

10  192.168.1.1
11  192.168.1.2
12  192.165.2.4
13  122.11.22.11    
13  192.168.1.1
13  192.168.1.2
13  122.11.22.11
14  122.11.22.11
15  122.11.22.11
15  122.11.22.144
15  122.11.2.11
15  122.11.22.111

我应该得到的是:

10  192.168.1.1
11  192.168.1.2
12  192.165.2.4
13  122.11.22.11    
15  122.11.22.144
15  122.11.2.11
15  122.11.22.111

感谢您的帮助,我成功地创建了适合我需要的脚本:

awk '
FILENAME == ARGV[1] {
    ip[$2] = 1
    next
}
! ($2 in ip) {
    print $1, $2 >> ARGV[1]
    ip[$2] = 1
}
' list.txt file.txt 
4

4 回答 4

3

将问题解释为“如何从 awk 中评估命令的状态?”,只需使用 system.

{
  如果(系统(“cmd”)== 0){
    # 命令成功
  {
}

因此,就您而言,只需执行以下操作:

{
  如果(系统(“grep -w \”“$3”\“list.txt > /dev/null”)== 0){
    ...
  }
}

不过,您可能需要重新考虑解决问题的方法。每次 Grepping 的计算成本很高,并且有更好的方法来解决这个问题。(例如,将 list.txt 读入一次数组。)

另外,请注意您不需要使用 wc。如果与字符串不匹配,则 grep 失败。使用返回值而不是解析输出。

于 2011-10-12T15:02:19.060 回答
2

这会将执行结果保存到变量 a

BEGIN {  } 
{
"grep -w \"$3\" list.txt | wc -c" | getline a
print a
}
END   {}
于 2011-10-12T15:04:27.843 回答
1

但实际上你想要做的是让 awk 先读取 list.txt 文件,然后用内存中的 list.txt 数据处理另一个文件。这将允许您避免调用system()每条线路。

我假设 ip 在 list.txt 的第一列。

当您说 时copy timestamp and ip in list.txt,我假设您想将 file.txt 当前行中的一些信息附加到 list.txt 文件中。

awk '
    FILENAME == ARGV[1] {
        ip[$1] = 1
        next
    }
    ! ($3 in ip) {
        print $3, $(whatevever_column_holds_timestamp) >> ARGV[1]
    }
' list.txt file.txt

鉴于您的问题更新的示例文件和简化要求:

awk '! seen[$2]++' filename

将产生您所看到的结果。如果尚未看到 IP,则该 awk 程序将打印该行。

于 2011-10-12T16:06:23.577 回答
1

你想使用getline

BEGIN {
    "date" | getline current_time
     close("date")
     print "Report printed on " current_time
}

这需要输出date并将其放入 current_time 变量中。你应该可以用你的 grep | 做同样的事情。厕所-l。

于 2011-10-12T14:42:27.780 回答