【问题标题】:How can i do this without "awk" in shell script我如何在 shell 脚本中没有“awk”的情况下做到这一点
【发布时间】:2021-02-19 21:39:42
【问题描述】:

我想读取带有某些条件的文本文件

111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 123"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /favicon.ico HTTP/1.1" 404 - "
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 206"
111.196.10.3 - - [20/Jan/2020:19:43:50 +0200] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 377"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /sit-3-shine.7.gif HTTP/1.1" 404 - "
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 375"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET /sit3-shine.7.gif HTTP/1.1" 200 15811"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 375"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET /sit3-shine.7.gif HTTP/1.1" 200 15811"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 299"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /sit3-shine.7.gif HTTP/1.1" 200 15811"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 299"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET /sit3-shine.7.gif HTTP/1.1" 200 15811"
111.196.10.2 - - [20/Jan/2020:07:00:50 +0100] "GET /favicon.ico HTTP/1.1" 404 -"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "HEAD / HTTP/1.1" 304 299"
111.196.10.3 - - [20/Jan/2020:07:00:50 +0100] "GET / HTTP/1.1" 200 302"
111.196.10.1 - - [20/Jan/2020:07:00:50 +0100] "GET /thttpd_powered_2.gif HTTP/1.1" 200 2114"

1:我想要一个脚本来计算文本文件中的 IP 地址并给我这样的输出

111.196.10.1  8
111.196.10.2  8
111.196.10.3  7

针对以上,我写了一个脚本

cat file | awk '{print $1}' | sort | uniq -c | sort -nr | awk '{print $2" "$1}'

它工作正常,但我想要这个没有“awk”

2:我的第二个要求是,仅当行的倒数第二个数字以2开头时才计算IP地址。输出将是

111.196.10.1  7
111.196.10.3  7
111.196.10.2  5

为此,我写了一个脚本

grep '^[^"]*"[^"]*" 2' file | cut -d' ' -f1 | sort | uniq -c | sort -nr | awk '{print $2" "$1}'

它也可以正常工作,但我想要这个没有“awk”

【问题讨论】:

  • 我建议用 GNU awk 做所有事情。
  • 为什么要在没有awk 的情况下执行这些操作?这是处理此类事情的最佳工具之一。
  • @Barmar 感谢您回复我,我们的任务是,在没有“awk”的情况下执行此操作
  • 欢迎来到 Stack Overflow! StackOverflow 不是免费的编码服务。你应该try to solve the problem first。请更新您的问题以在minimal reproducible example 中显示您已经尝试过的内容。如需更多信息,请参阅How to Ask,并拨打tour :)
  • 你可以看看 man cut

标签: bash shell unix awk


【解决方案1】:

您可以使用read 从输入中读取两个字段,然后以不同的顺序回显它们。

所以替换

awk '{print $2" "$1}'

while read count ip; do
    echo "$ip $count"
done

【讨论】:

  • 无论如何,这个特殊的下标似乎完全没用。如果任务是从uniq 输出中修剪空白,这将起作用,但缓慢而模糊。也许sed 's/ */ /g;s/^ //'*之前应该有两个空格@
  • 对于 packslashes 的健壮性,更喜欢 read -r(在这里可能没有用,但在现代脚本中应该是所有地方的默认设置)。
  • 我不得不反对@tripleee 的建议,即-r 应被视为最佳实践。相反,工具应该使用转义的换行符,并且应该尽可能避免使用 -r
  • @tripleee 我认为任务是交换uniq -c 输出中字段的顺序。
【解决方案2】:

没有awk

grep -oE '([0-9]+\.){3}[0-9]+' Input_file | sort | uniq -c


awk:

您能否尝试关注,在单个awk 中完成。

awk '
match($1,/([0-9]+\.){3}[0-9]+/){
  arr[substr($0,RSTART,RLENGTH)]++
}
END{
  for(key in arr){
    print key,arr[key]
  }
}
' Input_file

或者如果第一个字段只是ip地址,那么我们不需要在数组索引中提到substr,我们可以直接使用$1,如下所示。

awk '
match($1,/([0-9]+\.){3}[0-9]+/){
  arr[$1]++
}
END{
  for(key in arr){
    print key,arr[key]
  }
}
'  Input_file

说明:为上述添加详细说明。

awk '                                 ##Starting awk program from here.
match($1,/([0-9]+\.){3}[0-9]+/){      ##using match function to match IP address regex in current line.
  arr[substr($0,RSTART,RLENGTH)]++    ##Create array arr which has index as sub string of matched regex from RSTART to RLENGTH.
}
END{                                  ##Starting END block of this program from here.
  for(key in arr){                    ##Traversing through arr from here.
    print key,arr[key]                ##printing key and array value here.
  }
}
' Input_file                          ##Mentioning Input_file name here.

【讨论】:

    【解决方案3】:
    1. 您可以使用 Cut 仅获取第一列,然后对生成的 IP 进行排序并使用 Uniq 对其进行计数。

      cut -f1 -d' ' file | sort -n | uniq -c
      
    2. 如果您只想在倒数第二个数字以2 开头时计入该行,则只需添加一个 Grep。

      grep -E '2[0-9]* [0-9]+"$' t | cut -f1 -d' ' | sort -n | uniq -c
      

    在样本输入上测试。

    【讨论】:

      猜你喜欢
      • 2020-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2019-01-18
      • 1970-01-01
      • 2022-01-19
      相关资源
      最近更新 更多