【发布时间】: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 sed、man awk、man bash是你最好的朋友。如果找不到您搜索的内容,请尝试通常更完整的info而不是man。 -
试试很酷的 sed 调试器sedsed。