在 awk 上使用 system() 函数在第一列上运行命令

hol*_*asz 5 linux awk shell-script gawk

我有以下代码,我正在运行它来提取一些 IP 地址并计算它们的唯一性。例如

./my_program | awk '/^10./{a[$1 FS $2]++ } END { for(i in a) print i,a[i]}' > some_file
Run Code Online (Sandbox Code Playgroud)

some_file包含的输出是这样的:

10.12.33.14 34
10.12.33.11 12
10.12.33.16 5
Run Code Online (Sandbox Code Playgroud)

现在我想要的是运行{system("dig +short -x " i)}并将输出追加到最后一列,以便文件看起来像

10.12.33.14 34  server1.rdns.domain.tld
10.12.33.11 12  server2.rdns.domain.tld
10.12.33.16 5   server3.rdns.domain.tld
Run Code Online (Sandbox Code Playgroud)

我可以一次性完成此操作,然后将输出通过管道传输到文本文件吗?

谢谢!

更新1

... END { for(i in a) cmd=sprintf("dig +short -x \"%s\"", $i); cmd | getline type; close(cmd);  printf("%s %s %s\n",i,a[i],type);
Run Code Online (Sandbox Code Playgroud)

这就是输出(stderr)的结尾

dig: '.in-addr.arpa.' is not a legal name (unexpected end of input)
Run Code Online (Sandbox Code Playgroud)

这是我在文件中看到的

10.12.33.14 34
Run Code Online (Sandbox Code Playgroud)

更新2:

    END { for(i in a) split(i,ip," ")
    cmd=sprintf("dig +short -x \"%s\"", ip[1]); cmd | getline type; close(cmd);
    printf("%s %s %s %s\n",ip[1],ip[2],a[i],type)
Run Code Online (Sandbox Code Playgroud)

Ini*_*ian 6

您可以使用split()function 拆分 IP/端口组合并获取 IP 以供稍后在dig()命令中使用。

END { 
  for(i in a) {
    split(i, ip)
    cmd=sprintf("dig +short -x \"%s\"", ip[1])
    (cmd | getline type) > 0 ? "" : type="notResolved"
    printf("%s %s %s\n",i,a[i],type);
    close(cmd)
  }
}
Run Code Online (Sandbox Code Playgroud)

我添加了一种检查dig命令状态的方法,并使用?三元运算符来更新类型的值。对于失败的情况,您可以添加自己的字符串(例如'notResolved'在上面)并打印结果。

请注意,使用getline()call inawk与使用system()call 不同。该类型cmd | getline var使用管道,就像cmd从 shell 运行一样,每次调用都会getline var从命令中读取一行输出。该system()命令虽然没有提供获取在内部执行的命令的输出的方法。您只能访问从内部运行的命令返回的退出代码。

PS答案部分采用了muru的有用评论


Pus*_*mar 1

您可以执行以下操作

步骤1:

./my_program | awk '/^10./{a[$1]++ } END { for(i in a) print i,a[i]}' | tee some_file | xargs -I{} dig +short -x {} > some_file2
Run Code Online (Sandbox Code Playgroud)

第2步:

paste <(awk '{print $1}' some_file ) <(awk '{print $1}' some_file2 ) > result
Run Code Online (Sandbox Code Playgroud)

如果您愿意,您可以删除some_filesome_file2rm some_file some_file2