【问题标题】:How did sed 's/.*\[//g;s/].*//g;s/:.*//g' work heresed \'s/.*\\[//g;s/].*//g;s/:.*//g\' 如何在这里工作
【发布时间】:2022-11-17 07:37:14
【问题描述】:

关于sed的问题。

使用这个命令 sed 's/.*\[//g;s/].*//g;s/:.*//g'

有了这个输入

172.19.0.100 - - [16/Feb/2020:22:31:32 +0000] "GET /site HTTP/1.1" 200 36565 "https://command-not-found.com/curl" "Mozilla/5.0+(compatible; UptimeRobot/2.0; http://www.uptimerobot.com/)" "172.19.0.3"
172.19.0.101 - - [16/Feb/2020:22:30:10 +0000] "GET /credits HTTP/1.1" 200 31067 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "172.19.0.2"
172.19.0.102 - - [17/Feb/2020:22:30:10 +0000] "GET /index HTTP/1.1" 200 31067 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "172.19.0.2"
172.19.0.100 - - [18/Feb/2020:22:35:10 +0000] "GET /index HTTP/1.1" 200 31067 "-" "Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" "172.19.0.2"

任何人都可以引导我逐步了解 sed 的作用吗?我正在尝试更熟练地使用它,这对我来说有点不知所措

预期结果

1 18/Feb/2020
1 17/Feb/2020
1 15/Feb/2020

我尝试在https://sed.js.org/ 上玩弄它,但它一直说无法读取文件。

我试图阅读和理解的整个代码是这样的。

#!/usr/bin/env bash
LOG_FILE="$1"

function request_per_day() {
    declare -A day_array
    while read line; do
        day=$(echo "$line" | sed 's/.*\[//g;s/].*//g;s/:.*//g')
        if [[ -v day_array[$day] ]]; then
            day_array[$day]=$((day_array[$day]+1))
        else
            day_array[$day]=1
        fi
    done < $LOG_FILE

    for day in ${!day_array[@]}; do echo ${day_array[$day]} $day; done | sort -rn | head -10
}

function request_per_ip() {
    declare -A ip_array
    while read line; do
        ip=$(echo $line | awk '{print $1}')
        if [[ -v ip_array[$ip] ]]; then
            ip_array[$ip]=$((ip_array[$ip]+1))
        else
            ip_array[$ip]=1
        fi
    done < $LOG_FILE

    for ip in ${!ip_array[@]}; do echo ${ip_array[$ip]} $ip; done | sort -rn | head -10
}

request_per_day
echo ""
request_per_ip

虽然我了解其中的大部分内容,但我并不真正了解 sed 和 awk 在这个示例中是如何工作的。

最后,if [[ -v day_array[$day] ]] 究竟测试了什么?

【问题讨论】:

  • 尝试通过在 SO 中删除示例并要求逐步解释来学习sed之类的东西是非常低效的。如果您无法理解您显示的相当简单的sed 脚本,最好的办法可能是阅读手册。 man sedman awkman bash 是你最好的朋友。如果找不到您搜索的内容,请尝试通常更完整的 info 而不是 man
  • 试试很酷的 sed 调试器sedsed

标签: bash unix sed


【解决方案1】:

发布这个问题后,我设法偶然发现了一个资源,它基本上回答了如何将 sed 命令和通配符串在一起。设法弄清楚了。

这是他们所做的和他们的结果。

s/.*[//g

搜索[ 之前的所有模式,并用任何内容替换它们(删除它们),结果将是:

15/Feb/2020:22:32:02 +0000] "GET /index HTTP/1.1" 200 14034 "-" "Mozilla/5.0 (compatible; SemrushBot/6~bl; +http://www.semrush.com/bot.html)" "172.19.0.4"

下一个 sed 命令是

s/].*/g

现在,这将搜索 ] 之后的任何内容,并用任何内容替换它们(删除它们),这会产生以下结果:

15/Feb/2020:22:32:02 +0000

最后

s/:.*//g

这将搜索 : 之后的任何内容,并用任何内容替换它们,从而导致

15/Feb/2020

【讨论】:

    猜你喜欢
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多