wys的个人博客

你有很多事放不下?做人要潇洒一点~

0%

Data Wrangling

Data Wrangling

以下代码可以查看服务器的日志

1
ssh myserver journalctl

需要注意的是 myserver 由,<用户名>@<$ip$地址构成>

sed 是一种匹配工具,s 命令的形式如下:s/REGEX/SUBSTITUTION/ 其中 REGEX 是正则表达式,而SUBSTITUTION 是替代文本,也就是将匹配到的正则表达式转换为代替文本,默认只替代一遍。在后面加上g 可以多次匹配。

为了支持更不用加上\ 我们需要在sed后加上-E

以下是该命令的一些示例用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
rust@DESKTOP-L4PLVQ4:~$ echo 'aba' | sed 's/[ab]//'
ba
rust@DESKTOP-L4PLVQ4:~$ echo 'bba' | sed 's/[ab]//'
ba
rust@DESKTOP-L4PLVQ4:~$ echo 'bba' | sed 's/[ab]//g'

rust@DESKTOP-L4PLVQ4:~$ echo 'bbac' | sed 's/[ab]//g'
c
rust@DESKTOP-L4PLVQ4:~$ echo 'bcbzac' | sed 's/[ab]//g'
czc
rust@DESKTOP-L4PLVQ4:~$ echo 'abcaba' | sed -E 's/(ab)*//g'
ca
rust@DESKTOP-L4PLVQ4:~$ echo 'abcaba' | sed 's/\(ab\)*//g'
ca
rust@DESKTOP-L4PLVQ4:~$ echo 'abcabbc' | sed -E 's/(ab|bc)*//g'
c

先把有关 Disconnected from 的日志文件都过滤出来。

1
2
3
sudo ssh ubuntu@101.35.*.* 'journalctl 
| grep ssh
| grep "Disconnected from"'> ssh.log

以下命令可以将Disconnected from 全部替换为空行。

1
2
cat ssh.log 
| sed 's/.*Disconnected from//'

以下命令可以将整行进行替换。

1
2
3
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?(user .* )?[0-9.]+ port [0-9]+( \[preauth\])?$//'
| head -n70

被圆括号内的正则表达式匹配到的文本,都会被存入一系列以编号区分的捕获组中。捕获组的内容可以在替换字符串时使用(有些正则表达式的引擎甚至支持替换表达式本身),例如\1\2\3等等.

因此以下命令可以只保留用户名

1
2
3
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| head -n70

以下命令可以将查找结果排序:

1
2
3
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort

以下代码可以去重并计数:

1
2
3
4
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c

以下代码可以查看有多少行:

1
2
3
4
5
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| wc -l

以下代码可以查看十个最多的用户名:

1
2
3
4
5
6
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| sort -nk1,1
| tail -n10

sort -n 会按照数字顺序对输入进行排序(默认情况下是按照字典序排序 -k1,1 则表示“仅基于以空格分割的第一列进行排序”。,n 部分表示“仅排序到第n个部分”,默认情况是到行尾。就本例来说,针对整个行进行排序也没有任何问题,我们这里主要是为了学习这一用法!

awk 可以以列为对象操作数据,而paste -s可以将内容粘贴进一行,d, 可以将一行中的数据用间隔符‘,’分开

1
2
3
4
5
6
7
8
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| sort -nk1,1
| tail -n20
| awk '{print $2}'
| paste -sd,

以下命令可以找出只出现一次并且以c开头以c结尾的用户名

1
2
3
4
5
6
7
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| sort -nk1,1
| awk '$1 == 1 && $2 ~ /^c.*c$/ {print $0}'
1 contec

以下两条命令可以起到同样的效果

1
2
3
4
5
6
7
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| sort -nk1,1
| awk '$1 == 1 && $2 ~ /^c.*c$/ {print $0}'
| wc -l
1
2
3
4
5
6
7
8
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| sort -nk1,1
| awk 'BEGIN {rows = 0 }
$1 == 1 && $2 ~ /^c.*c$/ {rows += 1}
END { print rows }'

BEGIN 也是一种模式,它会匹配输入的开头( END 则匹配结尾)。然后,对每一行第一个部分进行累加,最后将结果输出。

事实上,我们完全可以抛弃 grepsed ,因为 awk 就可以解决所有问题。但是这样会十分painful

bc可以对字符串进行数值计算。

1
2
3
4
5
6
7
8
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| sort -nk1,1
| awk '$1 != 1 { print $1 }'
| paste -sd+
| bc -l

以上代码可以将数量不是1的用户数相加,先把它们打印到一行用 + 分隔,最后用bc相加。

可以用R语言对数据进行处理

1
2
3
4
5
6
7
8
9
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| sort -nk1,1
| awk '$1 != 1 { print $1 }'
| R --slave -e 'x <- scan(file="stdin", quiet=TRUE); summary(x)'
Min. 1st Qu. Median Mean 3rd Qu. Max.
2.00 3.00 5.00 68.68 9.00 8121.00

也可以用gunplot 进行绘图,但是bash好像不支持gnuplot

1
2
3
4
5
6
7
8
9
cat ssh.log 
| sed -E 's/^.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( \[preauth\])?$/\2/'
| sort
| uniq -c
| sort -nk1,1
| awk '$1 != 1 { print $1 }'
| tail -n10
| gnuplot -p -e 'set boxwidth 0.5; plot "-" using 1:xtic(2) with boxes'