如何通过查询字符串值使用awk正则表达式排序?

时间:2022-01-13 18:41:05

I have a log file with example row:

我有一个带有示例行的日志文件:

xxx.xxx.xxx.xxx - - [07/Jun/2015:14:18:39 +0000] "GET /file/?t=70 HTTP/1.1" 200 35 "http://1234.com/p/talk-about-owning-it/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome"

The 7th column of each row looks like this:

每行的第7列如下所示:

/file/?t=70
/file/?t=4785&k=1
/file/?t=120
/file/?t=95&k=0
/file/?t=120
/file/?t=120&k=0
/file/?t=95&k=1
...

Output is arranged according to the number of lines in decreasing order containing unique values of t.

输出根据包含唯一值t的递减顺序的行数排列。

Desired OUTPUT:

期望的输出:

120  -  3
95   -  2
4785 -  1
70   -  1
...

I am using awk but it is not giving desired output:

我使用awk但它没有提供所需的输出:

awk -F'[=&]' '{print $2}' /var/log/nginx/t.access.log | sort | uniq -c | sort -rn

It outputs all columns after 7th which is not required. What am I doing wrong? Any suggestions please.

它输出7号后的所有列,这是不需要的。我究竟做错了什么?请给我任何建议。

2 个解决方案

#1


2  

Using your 1 sample input line:

使用您的1个样本输入行:

$ awk '{split($7,a,/[=&]/); print a[2]}' file | sort | uniq -c | sort -rn
      1 70

or if the rest of your input lines follow EXACTLY the format of that one line:

或者如果输入行的其余部分完全遵循那一行的格式:

$ awk -F'[=& ]' '{print $8}' file | sort | uniq -c | sort -rn
      1 70

or entirely in awk:

或完全在awk中:

$ cat tst.awk
{
    split($7,a,/[=&]/)
    sum[a[2]]++
}
END {
    PROCINFO["sorted_in"] = "@val_num_desc"
    for (val in sum) {
        print val "\t- " sum[val]
    }
}
$ awk -f tst.awk file
70      - 1

or:

要么:

$ cat tst.awk
BEGIN { FS="[=& ]" }
{ sum[$8]++ }
END {
    PROCINFO["sorted_in"] = "@val_num_desc"
    for (val in sum) {
        print val "\t- " sum[val]
    }
}
$
$ awk -f tst.awk file
70      - 1

The above uses GNU awk 4.* for PROCINFO["sorted_in"] to sort the output. If you don't have that, remove that line and pipe to sort -rn with appropriate args. You do not need the intermediate | sort | uniq -c either way.

以上使用GNU awk 4. * for PROCINFO [“sorted_in”]对输出进行排序。如果没有,请删除该行和管道以使用适当的args对-rn进行排序。你不需要中间体|排序| uniq -c无论哪种方式。

#2


0  

This should do the job:

这应该做的工作:

cat file.dat
xxx.xxx.xxx.xxx - - [07/Jun/2015:14:18:39 +0000] "GET /file/?t=70 HTTP/1.1" 200 35 "http://1234.com/p/talk-about-owning-it/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome"
xxx.xxx.xxx.xxx - - [07/Jun/2015:14:18:39 +0000] "GET /file/?t=70 HTTP/1.1" 200 35 "http://1234.com/p/talk-about-owning-it/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome"
xxx.xxx.xxx.xxx - - [07/Jun/2015:14:18:39 +0000] "GET /file/?t=72 HTTP/1.1" 200 35 "http://1234.com/p/talk-about-owning-it/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome"

awk -F" " 'BEGIN{FS="=|&| "}{print $8}' file.dat | sort | uniq -c | sort -rn
2 70
1 72

EXPLANATION: I used multiple separators, then your field is number 8, and just used your ordering code.

说明:我使用了多个分隔符,然后你的字段是8号,只是使用了你的订购代码。

Hope it helps

希望能帮助到你

#1


2  

Using your 1 sample input line:

使用您的1个样本输入行:

$ awk '{split($7,a,/[=&]/); print a[2]}' file | sort | uniq -c | sort -rn
      1 70

or if the rest of your input lines follow EXACTLY the format of that one line:

或者如果输入行的其余部分完全遵循那一行的格式:

$ awk -F'[=& ]' '{print $8}' file | sort | uniq -c | sort -rn
      1 70

or entirely in awk:

或完全在awk中:

$ cat tst.awk
{
    split($7,a,/[=&]/)
    sum[a[2]]++
}
END {
    PROCINFO["sorted_in"] = "@val_num_desc"
    for (val in sum) {
        print val "\t- " sum[val]
    }
}
$ awk -f tst.awk file
70      - 1

or:

要么:

$ cat tst.awk
BEGIN { FS="[=& ]" }
{ sum[$8]++ }
END {
    PROCINFO["sorted_in"] = "@val_num_desc"
    for (val in sum) {
        print val "\t- " sum[val]
    }
}
$
$ awk -f tst.awk file
70      - 1

The above uses GNU awk 4.* for PROCINFO["sorted_in"] to sort the output. If you don't have that, remove that line and pipe to sort -rn with appropriate args. You do not need the intermediate | sort | uniq -c either way.

以上使用GNU awk 4. * for PROCINFO [“sorted_in”]对输出进行排序。如果没有,请删除该行和管道以使用适当的args对-rn进行排序。你不需要中间体|排序| uniq -c无论哪种方式。

#2


0  

This should do the job:

这应该做的工作:

cat file.dat
xxx.xxx.xxx.xxx - - [07/Jun/2015:14:18:39 +0000] "GET /file/?t=70 HTTP/1.1" 200 35 "http://1234.com/p/talk-about-owning-it/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome"
xxx.xxx.xxx.xxx - - [07/Jun/2015:14:18:39 +0000] "GET /file/?t=70 HTTP/1.1" 200 35 "http://1234.com/p/talk-about-owning-it/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome"
xxx.xxx.xxx.xxx - - [07/Jun/2015:14:18:39 +0000] "GET /file/?t=72 HTTP/1.1" 200 35 "http://1234.com/p/talk-about-owning-it/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome"

awk -F" " 'BEGIN{FS="=|&| "}{print $8}' file.dat | sort | uniq -c | sort -rn
2 70
1 72

EXPLANATION: I used multiple separators, then your field is number 8, and just used your ordering code.

说明:我使用了多个分隔符,然后你的字段是8号,只是使用了你的订购代码。

Hope it helps

希望能帮助到你