【问题标题】:Understanding IN Statement in awk理解 awk 中的 IN 语句
【发布时间】:2020-12-31 07:19:29
【问题描述】:

我在理解 bash 中的 in 语句时遇到了问题...首先是代码:

#! /bin/bash

dns=()
while read line; do
  up=$(nslookup $line | awk -F ': ' 'NR==6 {print $2} ')
  dns+=($up)
done < dns.blacklist.txt.txt

awk '{if( $1 in dns ) print $1 " Blacklisted"; else print $1}' thttpd2.log 

所以thttp2.log 只是一个 IP 列表,而 nslookup 正在获取主机名的 IP(用于黑名单目的)。所以现在我想检查日志中连接的IP是否在黑名单上,在dns数组的代码中。

来自nslookup 的所有 IP 和查找都很好: Dns=81.169.145.82 192.0.3.45 和 awk $1=81.169.145.82 。那么,如果$1在dns中,如何查看下部的awk语句?

我已经尝试了半天了......我很确定我没有理解“in”所以有人可以请至少给我一个提示吗?

PS:目前的结果只是:

81.169.145.82
81.169.145.82
81.169.145.82
192.0.3.45

目标:

81.169.145.82 Blacklisted
81.169.145.82 Blacklisted
81.169.145.82 Blacklisted
192.0.3.45

【问题讨论】:

  • 在您的示例中,dns 是一个 bash 数组。 awk 是从 (bash) shell 运行的程序。您不能从 awk 内部直接访问 bash 数组的内容,就像在 python 程序中无法访问和使用 bash 变量一样。
  • 另外,您编写了一个bash 循环来将文本文件的内容读入一个数组,并且您的意图是将此内容用作awk 的输入。虽然awk 的理想输入是一个文件,而您已经拥有该文件,所以您必须向awk 提供两个文件参数并在其中执行任何操作。
  • ...话虽如此,in 语句(是awk 而不是bash)类似于python。你可以说for (i in a)if (i in a)a 应该是awk 数组,而不是bash 一个,
  • @thanasisp 所以现在我将我的数组转移到 awk 到一个名为 a 的数组,但仍然没有成功? awk -v A="${dns[0]}" 'BEGIN {c=split(A,a)}' | awk '{if( $1 in a ) print $1 " blacklisted"; else print $1}' thttpd2.log
  • ${dns[0]} 只是数组的第一个元素。

标签: arrays linux bash if-statement awk


【解决方案1】:

使用while 循环的输出作为awk 输入似乎更好,没有理由在中间使用bash 数组,awk 比任何bash 变量更喜欢流。

因此,您生成了一个 ips 流,读取您的 blacklist.txt 文件并解析 nslookup 输出。我在我的回答中将该部分视为黑匣子,我假设您获得了良好的结果并希望使用其他文件运行您的逻辑。此外,在输入量很大的情况下,每行运行一个 nslookup 和一个 awk 效率不高,但我不知道你在那部分做了什么,我保持原样。

while read -r line; do
    nslookup "$line" | awk -F ': ' 'NR==6 {print $2}'
done < blacklist.txt | awk 'FNR==NR {dns[$0]; next}
                       {print ($1 in dns)? $1 " Blacklisted": $1}' - thttpd2.log

您也可以直接将黑名单文件提供给awk,并在awk 内部调用您使用的外部bash 命令。但我认为这样更简单。

【讨论】:

    【解决方案2】:

    那么如果 $1 在 dns 中,我如何检查下部的 awk 语句?

    awk 不是外壳,外壳也不是 awk。 Shell 变量与任何 awk 变量无关,awk 变量与 shell 无关。 awk 是一个单独的程序,其语法与 shell 无关,而 shell 是一个单独的程序,其语法与 awk 无关。

    construct subscript in arrayawk 语法的一部分,用于检查awk 中的下标下标 是否是awk 数组数组 中的下标之一。它与 shell 变量和 bash 数组无关。请注意,下标不是元素的值,而是索引。 "数组[下标]=值"

    理解 IN - Linux bash 中的语句

    bash shell 中的in 仅用作case 语句中的关键字:

    case something in
    pattern) ;;
    esac
    

    它的用法与awk的用法无关,因为shell不是awk

    请至少给我一个小费?

    首先将输入读入awk,作为数组dns的下标。之后,您可以使用 awk 构造 something in dns 来检查某物是否是数组的下标。

    【讨论】:

      【解决方案3】:

      您已经得到了解释 in 含义的答案,而且 - 因为 nslookup 可以从标准输入读取域名列表:

      $ cat dns.blacklist.txt.txt
      google.com
      yahoo.com
      
      $ nslookup < dns.blacklist.txt.txt
      Default Server:  cdns01.foo.net
      Address:  2222:555:beef::1
      
      > Server:  cdns01.foo.net
      Address:  2222:555:beef::1
      
      Non-authoritative answer:
      Name:    google.com
      Addresses:  2607:f8b0:4009:804::200e
                172.217.9.78
      
      > Server:  cdns01.foo.net
      Address:  2222:555:beef::1
      
      Non-authoritative answer:
      Name:    yahoo.com
      Addresses:  2001:4998:44:3507::8000
                2001:4998:124:1507::f001
                2001:4998:124:1507::f000
                2001:4998:44:3507::8001
                2001:4998:24:120d::1:1
                2001:4998:24:120d::1:0
                98.137.11.163
                74.6.143.25
                74.6.231.21
                98.137.11.164
                74.6.143.26
                74.6.231.20
      

      你不需要在 shell 循环中包装任何东西,例如(未经测试):

      nslookup < dns.blacklist.txt.txt |
      awk '
          NR==FNR {
              if ( sub(/^Addresses:/,"") ) { inAddrs=1 }
              if ( inAddrs ) {
                  if ( NF ) { dns[$1] }
                  else { inAddrs=0 }
              }
              next
          }
          { print $1, ($1 in dns ? "Blacklisted" : "" }
      ' - thttpd2.log
              
      

      请注意,nslookup 可以输出给定域的 IP 地址列表,而不仅仅是您现有脚本所期望的 1,并且上面的脚本将适应这种情况。

      【讨论】:

        猜你喜欢
        • 2014-06-16
        • 2015-07-24
        • 2014-12-28
        • 2021-02-03
        • 2010-11-15
        • 2013-06-22
        • 1970-01-01
        • 2014-09-24
        • 1970-01-01
        相关资源
        最近更新 更多