https://missing.csail.mit.edu/
https://missing-semester-cn.g...
https://www.bilibili.com/vide...
ssh myserver journalctl | grep sshd | grep "Disconnected from" | sed -E 's/.*Disconnected from (invalid |authenticating )?user (.*) [0-9.]+ port [0-9]+( [preauth])?$/2/' | sort | uniq -c | sort -nk1,1 | tail -n10 | awk '{print $2}' | paste -sd,
sort -n
會按照數字順序對輸入進行排序(默認狀況下是按照字典序排序 -k1,1
則表示「僅基於以空格分割的第一列進行排序」。,n
部分表示「僅排序到第n個部分」,默認狀況是到行尾。就本例來講,針對整個行進行排序也沒有任何問題,咱們這裏主要是爲了學習這一用法!github
若是咱們但願獲得登錄次數最少的用戶,咱們可使用 head
來代替tail
。或者使用sort -r
來進行倒序排序。編程
咱們能夠利用 paste
命令來合併行(-s
),並指定一個分隔符進行分割 (-d
)。bash
awk
實際上是一種編程語言,只不過它碰巧很是善於處理文本。服務器
awk
程序接受一個模式串(可選),以及一個代碼塊,指定當模式匹配時應該作何種操做。默認當模式串即匹配全部行(上面命令中當用法)。 在代碼塊中,$0
表示整行的內容,$1
到 $n
爲一行中的 n 個區域,區域的分割基於 awk
的域分隔符(默認是空格,能夠經過-F
來修改)。在這個例子中,咱們的代碼意思是:對於每一行文本,打印其第二個部分,也就是用戶名。ssh
再舉個例子,讓咱們統計一下全部以c
開頭,以 e
結尾,而且僅嘗試過一次登錄的用戶。編程語言
| awk '$1 == 1 && $2 ~ /^c[^ ]*e$/ { print $2 }' | wc -l
其中 wc -l
統計輸出結果的行數。ide
既然 awk
是一種編程語言,那麼則能夠這樣:學習
BEGIN { rows = 0 } $1 == 1 && $2 ~ /^c[^ ]*e$/ { rows += $1 } END { print rows }
BEGIN
也是一種模式,它會匹配輸入的開頭( END
則匹配結尾)。而後,對每一行第一個部分進行累加,最後將結果輸出。spa
bc (Berkeley Calculator) 是一個命令行計算器。例如這樣,能夠將每行的數字加起來:
| paste -sd+ | bc -l
下面這種更加複雜的表達式也能夠:
echo "2*($(data | paste -sd+))" | bc -l
-
雖然到目前爲止咱們的討論都是基於文本數據,但對於二進制文件其實一樣有用。例如咱們能夠用 ffmpeg 從相機中捕獲一張圖片,將其轉換成灰度圖後經過SSH將壓縮後的文件發送到遠端服務器,並在那裏解壓、存檔並顯示。
ffmpeg -loglevel panic -i /dev/video0 -frames 1 -f image2 - | convert - -colorspace gray - | gzip | ssh mymachine 'gzip -d | tee copy.jpg | env DISPLAY=:0 feh -'
其中 -frames 1
爲第一幀畫面,-f image2
將結果保存爲圖片而不是視頻格式。
命令中 -
表明標準輸入輸出流,例如 convert - -colorspace gray -
的意思是把標準輸入流的內容做爲程序的輸入,灰度處理後的結果再放到標準輸出流中。
words 文件能夠在這裏下載:/usr/share/dict/words
$ grep -E "^.*[aA].*[aA].*[aA].*$" /usr/share/dict/words \ | grep -vE "'s$" \ | sed -E "s/^.*(\w{2})$/\1/" \ | sort \ | uniq -ic \ | sort -r \ | head -n3 101 an 63 ns 51 ia
共存在多少種詞尾兩字母組合?顯然
$ echo "26*26" | bc -l 676
咱們把剛纔的詞尾保存下來,把全部的字母組合也保存爲文件。
$ grep -E "^.*[aA].*[aA].*[aA].*$" /usr/share/dict/words \ | grep -vE "'s$" \ | sed -E "s/^.*(\w{2})$/\1/" \ | sort \ | uniq -i > words.txt 2> words.txt $ cat words.txt | head -n5 aa ac ad ae ag $ echo {a..z}{a..z} | sed -E 's/ /\n/g' > full_words.txt $ cat full_words.txt | head -n5 aa ab ac ad ae
分別統計統計一下組合數:
$ wc -w full_words.txt 676 full_words.txt $ wc -w words.txt 110 words.txt
而後咱們找沒有出現過的組合,具體作法是把 words.txt 中的每一行做爲查找串,在 full_words.txt 中不匹配的行。
$ grep -F -v -f words.txt full_words.txt | head -n 5 ab af ai aj ao
結果應該共有 676 - 110 = 566
個,驗證一下:
$ grep -F -v -f words.txt full_words.txt | wc -w 566
用輸出重定向進行原地替換隻會獲得空文件。man sed
中能夠看到 sed 有 -i 選項,能夠進行原地替換。
-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if SUFFIX supplied)