Jai*_*ain 1 sorting bash awk grep
我是 shell 脚本(命令行)的新手。
通常,我只输入单行命令,但是,今天我从命令行排序和文本编辑排序得到不同的结果。
简而言之,我想知道为什么命令行“排序”与 vim 的“:排序”不同。
我有如下示例日志(文本)文件。
// log.txt
2021-04-12 10:00:00 [USER1000] login
2021-04-12 10:01:00 [USER1100] login
2021-04-12 10:02:00 [USER1010] login
2021-04-12 10:03:00 [USER1000] logout
2021-04-12 10:04:00 [USER1000] login
2021-04-12 10:05:00 [USER2000] login
2021-04-12 10:06:00 [USER1000] logout
2021-04-12 10:07:00 [USER1100] logout
2021-04-12 10:08:00 [USER1000] login
...
Run Code Online (Sandbox Code Playgroud)
我想知道谁以及一天“登录”了多少次。
所以,我为此使用cat, grep, sort, uniq。
// log.txt
2021-04-12 10:00:00 [USER1000] login
2021-04-12 10:01:00 [USER1100] login
2021-04-12 10:02:00 [USER1010] login
2021-04-12 10:03:00 [USER1000] logout
2021-04-12 10:04:00 [USER1000] login
2021-04-12 10:05:00 [USER2000] login
2021-04-12 10:06:00 [USER1000] logout
2021-04-12 10:07:00 [USER1100] logout
2021-04-12 10:08:00 [USER1000] login
...
Run Code Online (Sandbox Code Playgroud)
我认为它返回完美的结果,但它的顺序是不同的。
cat log.txt全部打印出来。2021-04-12 10:00:00 [USER1000] login
2021-04-12 10:01:00 [USER1100] login
2021-04-12 10:02:00 [USER1010] login
2021-04-12 10:03:00 [USER1000] logout
2021-04-12 10:04:00 [USER1000] login
2021-04-12 10:05:00 [USER2000] login
2021-04-12 10:06:00 [USER1000] logout
2021-04-12 10:07:00 [USER1100] logout
2021-04-12 10:08:00 [USER1000] login
Run Code Online (Sandbox Code Playgroud)
grep "login"仅过滤“登录”2021-04-12 10:00:00 [USER1000] login
2021-04-12 10:01:00 [USER1100] login
2021-04-12 10:02:00 [USER1010] login
2021-04-12 10:04:00 [USER1000] login
2021-04-12 10:05:00 [USER2000] login
2021-04-12 10:08:00 [USER1000] login
Run Code Online (Sandbox Code Playgroud)
grep -o.[USER1000]
[USER1100]
[USER1010]
[USER1000]
[USER2000]
[USER1000]
Run Code Online (Sandbox Code Playgroud)
uniq -c,sort所有“登录”文本。[USER1000]
[USER1000]
[USER1000]
[USER1010]
[USER1100]
[USER2000]
Run Code Online (Sandbox Code Playgroud)
uniq -c分组每篇课文。3 [USER1000]
1 [USER1010]
1 [USER1100]
1 [USER2000]
Run Code Online (Sandbox Code Playgroud)
sort多一查看登录人数。这一步,我附加了与大写无关的真实案例
1 [USER1000]
11 [USER1001]
2 [USER1002]
237 [USER1003]
4 [USER1005]
Run Code Online (Sandbox Code Playgroud)
它看起来像按文本而不是数字排序。
所以,我改变了 bash 命令
cat log.txt | grep "login" | grep -o "\[USER....\]" | sort | uniq -c | sort > login.txt
Run Code Online (Sandbox Code Playgroud)
没问题,但我只想知道“为什么不同”。
我也可以用命令行解决这个问题sort吗?
由于评论,我附加了我的测试代码图片。
当我写这个问题时,我用 vim:sort命令得到了正确的结果。
所有测试结果都在。
sort -n 让我得到我想要的结果。
使用此awk解决方案要容易得多:
awk '$NF == "login" {++freq[$(NF-1)]} END {for (i in freq) print i, freq[i]}' log.txt
[USER2000] 1
[USER1000] 3
[USER1100] 1
[USER1010] 1
Run Code Online (Sandbox Code Playgroud)
如果要对输出进行排序,请使用:
awk '$NF == "login" {++freq[$(NF-1)]} END {for (i in freq) print i, freq[i]}' log.txt | sort
[USER1000] 3
[USER1010] 1
[USER1100] 1
[USER2000] 1
Run Code Online (Sandbox Code Playgroud)
awk 参考资料: