使用空格和引号作为 awk 的分隔符

使用空格和引号作为 awk 的分隔符

做的时候

grep index.html /var/log/apache2/other_vhosts_access.log | awk '{print $1 $13}'

默认情况下,我们有一个空格分隔符。

如何同时使用"作为分隔符:

www.example.com:443 1.2.3.4 - - [01/Feb/2021:15:07:35 +0100] "GET /index.html HTTP/1.1" 200 8317 "https://www.example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"

awk例如我们可以使用?获取 IP 和用户代理

使用awk -F'["]'似乎没有效果。

预期的解析应该是:

www.example.com:443
1.2.3.4
-
-
[01/Feb/2021:15:07:35 +0100]
"GET /index.html HTTP/1.1" 
200 
8317 
"https://www.example.com/" 
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"

答案1

您需要在角色类中包含空格:

echo 'word1 word2"word2 word4"word5' | 
    awk -F '[ "]'  '{ for (i = 1; i <= NF; ++i) { print $i } }'

答案2

您需要 IP 地址和用户代理。

IP 地址是第二个空格分隔的单词。它将以默认值$2存在。awkFS

用户代理是最后一个双引号子字符串中的字符串。您可以通过删除最后一个双引号,然后删除直到现在最后一个双引号的所有内容来实现这一点。

awk

awk '{ ip = $2; sub("\"$",""); sub(".*\"",""); ua = $0; print ip; print ua }'

或者,稍微短一点,

awk '{ ip = $2; sub("\"$",""); sub(".*\"",""); print ip; print }'

sed

sed -e 'h' -e 's/[^ ]* //;s/ .*//p' \
    -e 'g' -e 's/"$//;s/.*"//'

这首先将行保存在保留空间 ( h) 中,然后通过删除直至第一个空间,然后从(现在的)第一个空间中删除来提取 IP 号码。这会隔离打印的 IP 号码。然后检索保存的行 ( g) 并应用与代码中相同的过程awk,即删除最后一个双引号,然后删除直到(现在)最后一个双引号的所有内容。

这两个命令都将 IP 号打印在一行上,然后在下一行上打印用户代理字符串。

相关内容