日誌處理中一些shell命令技巧

2022-03-30 00:08:56 字數 3428 閱讀 8580

陰差陽錯的做的日誌分析,前途未卜的這段日子,唯一還有點意思的可能就是手動的處理大量日誌。總結一下。

日誌檔案的輸入是動則幾個g的文字。從n個這樣的檔案中得到乙個列表,乙個數字,乙個比例。在什麼工具都沒有情況下,用shell命令不僅是驗證系統資料的準確性的方法,也是乙個很好的學習過程。

下面的一行典型的apache訪問日誌:

如果需要得到ip位址可以使用cut命令

cat log | cut -d ' ' -f1

-d ' '表示按照空格將行切開,-f1取第乙個字段,這樣得到的結果就是ip列表

有時候拿到的檔案是\t分隔,也可以使用cut切開,只不過需要多寫乙個$

[l]$ cat log | cut -d '\t' -f1 cut: the delimiter must be a single character #-d '\t'會報錯的 cut -f2 -d$'\t' infile #work

-c:complement,用set2替換set1中沒有包含的字元

-d:delete,刪除set1中所有的字元,不轉換

-s: squeeze-repeats,壓縮set1中重複的字元

-t: truncate-set1,將set1用set2轉換,一般預設為-t

如果拿到分割的檔案

cat log | tr -s ' ' ','
zzx@zzx103:~/dhcptest$ echo "aaacccddd ss " | tr -s [a-c]   # -s

acddd ss

zzx@zzx103:~/dhcptest$ echo "aaacccddd ss " | tr -s " " ","  #d和s之間有2個空格,替換後壓縮重複

aaacccddd,ss,

zzx@zzx103:~/dhcptest$ echo "aaacccddd ss " | tr -t " " ","

aaacccddd,,ss,

zzx@zzx103:~/dhcptest$ echo "aaacccddd  ss " | tr -s "a" "b" #替換後壓縮重複

bcccddd ss

將空格替換成,檔案變成csv

cat log | tr -d ' '

上面的命令直接刪除空格   

日誌處理後經常會出現空行,tr命令去掉空行的原理就是將連續兩個換行替換成乙個換行

cat log | tr -s '\n\n' '\n'

試想得到ip列表,欲得到獨立訪問的ip列表。

[l]$ cat log | cut -d ' ' -f1 | uniq -u

如果不僅僅是去重,還想統計每個ip訪問次數,可以加乙個引數c

[l]$ cat log | cut -d ' ' -f1 | uniq -uc

得到的格式形如:

1 126.193.38.128 5 49.98.156.154

前面的數字就是出現的次數

awk/seed是處理日誌的最終的萬金油。確實是什麼都可以做。awk/seed是一門很大的學問。這裡取我碰到的乙個日誌,日誌格式形如:

display=wvga|||lang=ja_jp|||isactive=1|||pixel=720x1280|||density=2.0|||version=5.7|||key=5146f54950f09f71750005ef|||out=abc'3|||uid=1

如果我需要得到isactive=1的日誌行,取到out=中'前一段,如上面的abc。

cat l | grep "isactive=1|" | awk 'match($0,/out=[^\x27]+/)'

grep的功能是篩選isactive=1的行。awk 後面跟''的是awk語言。$0總是代表當前匹配的字段值,match substr是awk可以用的函式,當match時後面{}中的**才會執行。當match,$0就是正則匹配的部分。rstart,rlength是awk可以使用的常量,分別表示開始匹配的開始下標,rlength是匹配的長度。

在''中需要再使用'光轉義是不行的,得用16進製制的**\x27。轉16進製制可以使用python**"'".encode("hex")得到

//驚訝awk就這麼簡單的解釋了,可這連入門都算不上。

試想我想得到兩個列表的交際,並集,差集,統計中經常會碰到,比如我想獲得昨天今天都在訪問的ip,其實就是今天的ip列表和昨天ip列表的交集。

先定義兩個簡單的檔案:

[ l]$ cat a.txt 1 2 3 4 5 [ l]$ cat b.txt 4 5 6 7 8 9

如果想得到ab的交集4 5 ,可以使用下面的命令:

sort -m a.txt b.txt | uniq -d 4 5

如果要得到並集1-9,可以:

sort -m a.txt b.txt | uniq 1 2 3 4 5 6 7 8 9

如果想得到ab的差集,即a去掉ab的交集1 2 3

comm -23 a.txt b.txt 1 2 3

同理:ba的差集:

comm -13 a.txt b.txt comm -23 b.txt a.txt

上述兩個命令等價

comm命令就是compare功能,如果什麼引數都不帶呢得到的什麼呢?

comm a.txt b.txt 1 2 3 4 5 6 7 8 9

diff命令以前經常看**改了哪些:

diff a.txt b.txt  1,3d0 < 1 < 2 < 3 5a3,6 > 6 > 7 > 8 > 9

竊以為能玩轉上面這些命令,處理個日誌問題不大了。

一篇介紹shell中集合操作的博文:

一直放在收藏夾的shell方面的部落格:

linux shell常用技巧

linux shell高階技巧 awk部分寫的獨好

Shell中一些簡單操作

為建立 echo hello shell out.txt 為追加 echo hello shell out.txt 當out.txt 文字不存在時,與 都會預設建立out.txt文字,並將hello shell 字串儲存到out.txt中 當out.txt文字存在時,會將out.txt文字中的內容清...

Shell指令碼中一些常用命令

1 pwd cat jdbc file grep password awk f 就是說輸入文字是通過冒號 來區分欄位的,如果你不用 f宣告分隔符,那麼awk預設是用空格 tab來分隔欄位的。比如你有 a.txt,內容是 hello world this is world 如果你用 awk a.txt...

Shell中一些特殊的變數

0 獲取當前執行shell的指令碼名。n獲取當前shell第n個引數,當大於9時,則用花括號括起來,例如 接的引數一空格隔開 獲取當前執行shell指令碼後面接的引數的個數 獲取當前shell指令碼所有傳參的引數。不加引號和 相同 如果加 上引號,如 相同。如果加上引號,如 相同。如果 加上引號 如...