天天看點

Linux 三劍客:grep/sed/awk

  • grep 更适合單純的查找或比對文本
  • sed 更适合編輯比對到的文本
  • awk 更适合格式化文本,對文本進行較複雜格式處理

grep

  • 格式:grep <參數> <比對模式> <檔案>
  • 參數:
    • -v 反向過濾(排除)
    • -n 顯示比對行及行号
    • -i 忽略大小寫
    • -c 統計比對的行數
    • -E 擴充(支援正則),同 egrep
    • –color=auto 對比對内容突出顔色
    • -w 按單詞查找
    • -o 隻輸出比對内容
    • -A 附加顯示比對行後的内容
    • -B 附加顯示比對行前的内容
    • -C 附加顯示比對行上下間的内容
    • -r 遞歸查找
  • 場景:更适合單純的查找或比對文本
  • 試例:
grep -v "books1" test1.txt
grep -n "books1" test1.txt
grep -n "." test1.txt # 類型于 cat -n test1.txt
grep -i "chenhao" test2.txt
grep -Ei "chenhao|books1" test2.txt
grep -c "chenhao" test2.txt # 統計數量
grep -o "books1" test2.txt # 隻輸出比對的内容
grep -w chenhao /etc/passwd # 隻比對單詞
grep -Ev "^$|#" nginx.conf # 過濾空行及注釋行
grep 'linux' test.txt test2.txt
grep -r "update" /etc/acpi/ #以遞歸的方式查找

grep '[a-z]\{7\}' *.txt # 過濾出每個字元串至少有7個連續小寫字元的字元串的行

grep chenhao$ test.txt # 過濾出以 chenhao 結尾的行
grep ^chenhao test.txt # 過濾出以 chenhao 開頭的行
grep ^[^c] test.txt # 過濾出非 c 開頭的行

# 過濾出 IP
ifconfig eth0|grep "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}"
ifconfig eth0|grep -E "([0-9]{1,3}\.){3}[0-9]"

ps aux | grep ssh | grep -v "grep" # grep不顯示本身程序
ps aux|grep \[s]sh
ps -ef|grep -c nginx

           

sed

  • 格式:sed <參數> <内置指令> <檔案>
  • 參數:
    • -n 取消預設輸出(常與内置指令 p 連用)
    • -i 直接修改檔案内容(危險動作)
    • -e 多點編輯
  • 内置指令:
    • a 行後追加
    • d 删除比對行
    • i 行前插入
    • p 列印比對行
    • c 取代内容
    • s/regexp/replacement/ 替換
  • 場景:更适合編輯比對到的文本
  • 試例:
sed '2a 106,dandan,CSO' persons.txt
sed '2i 106,dandan,CSO' persons.txt
sed -i '$a # This is a test' regular_express.txt # 在最後一行追加(直接改寫檔案)
sed '2a 106,dandan,CSO\n107,bingbing,CCO' person.txt
sed '2d' person.txt
sed '2,5d' person.txt
sed 's#zhangyao#dandan#g' person.txt
sed '2p' person.txt
sed -n '2p' person.txt
sed -n '2,3p' person.txt
sed -i '13i Port 52113\nPermitRootLogin no\nPermitEmptyPasswords no\nUseDNS no\nGSSAPIAuthentication no' /etc/ssh/sshd_config
sed -n '13,17p' /etc/ssh/sshd_config
sed -i 's/\.$/\!/g' regular_express.txt # 将 regular_express.txt 内每一行結尾若為 . 則換成 !
sed '1,20s/old/new/g' aa.txt

# 在第 4 行後添加内容
sed -e 4a\baidu test.txt

nl /etc/passwd | sed '2a Drink tea or \
drink beer ?'

# 将第 2~5 行的内容取代成為 test content
nl /etc/passwd | sed '2,5c test content'

# 搜尋有 root 關鍵字的行并輸出
nl /etc/passwd | sed -n '/root/p'

# 删除 /etc/passwd 所有包含 root 的行,其他行輸出
nl /etc/passwd | sed  '/root/d'

# -e 表示多點編輯,第一個編輯指令删除 /etc/passwd 第三行到末尾的資料,第二條指令搜尋 bash 替換為 blueshell
nl /etc/passwd | sed -e '3,$d' -e 's/bash/blueshell/'

# 過濾出 IP
/sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*addr://g' | sed 's/Bcast.*$//g'

# 找到 root 對應的行,執行後面花括号中的一組指令,每個指令之間用分号分隔,這裡把 bash 替換為 blueshell,再輸出這行,最後的 q 是退出
nl /etc/passwd | sed -n '/root/{s/bash/blueshell/;p;q}'   

           

awk

  • 格式:awk <參數> <模式 {動作}> 檔案
  • 參數:
    • -F 指定字段分隔符
    • -v 定義或個性一個 awk 内部的變量
    • -f 指定腳本檔案
  • 運算符:
    • = += -= *= /= %= ^= **= 指派
    • ?: C 條件表達式
    • && || ! 邏輯與/或/非
    • ~ ~! 比對正則 不比對正則
    • < <= > >= != == 關系運算符
    • 空格 連接配接
    • % / + - *
    • ^ *** 求幂
    • ++ –
    • $ 字段引用
    • 數組成員
  • 内建變量:
    • $0 表示整個目前行
    • $1 第 1 列
    • NF 目前行的字段的個數(列數)
    • NR 目前處理的文本行的行号,多檔案記錄遞增
    • FNR 各檔案分别計數的行号,多檔案記錄不遞增
    • FS 輸入字段分隔符(預設為空白字元)
    • OFS 輸出字段分隔符(預設為空白字元)
    • RS 輸入記錄分隔符(輸入換行符)
    • ORS 輸出記錄分隔符(輸出換行符)
    • ARGC 指令行參數的個數
    • ARGV 數組,儲存的是指令行所給定的各參數
  • 場景:更适合格式化文本,對文本進行較複雜格式處理
  • 試例:
awk -F "GET|HTTP" 'print $2' access.log
awk '$6~/Failed/{print $11}' /var/log/secure
awk 'NR==20,NR==30' filename
awk '{sum+=$0}END{print sum}' ett.txt
awk '{array[$1]++}END{for(key in array)print key,array[key]}' access.log

awk '{print}' /etc/passwd
awk '{print $0}' /etc/passwd

awk '{print $1,$4}' log.txt # 輸出第 1 及 第 4 列(預設以空格或 Tab 來分隔列)
awk '{printf "%-8s %-10s\n",$1,$4}' log.txt # 格式化輸出
awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd

awk -F, '{print $1,$2}' log.txt
awk 'BEGIN{FS=","} {print $1,$2}' log.txt
awk -F '[ ,]'  '{print $1,$2,$5}' log.txt #使用空格及 , 作為分割符

awk -va=1 '{print $1,$1+a}' log.txt # 設定變量并調用
awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt

awk '$1>2' log.txt # 過濾第一列大于 2 的行
awk '$1==2 {print $1,$3}' log.txt 
awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt

awk 'NR==5' test.txt
awk 'NR==2,NR==6' test.txt
awk '{print NR,$0}' test.txt # 類似 cat -n test.txt
awk 'NR==2,NR==6 {print NR,$0}' test.txt
awk -F ":" '{print $1,$3,$NF}' test.txt
awk '{gsub("/sbin/nologin", "/bin/bash", $0);print $0}' test.txt #将 /sbin/nologin 替換為 /bin/bash
ifconfig eth0|awk -F "(addr:)|( Bcase:)" 'NR==2{print $2}' # 取 IP位址
ifconfig eth0|awk -F "[ :]+" 'NR==2{print $4}'
awk -F '/' '{print $3}' books1.txt|sort|uniq -c
awk -F '/' '{hotel[$3]++;print $3,hotel[$3]}' books1.txt
awk -F '/' '{array[$3]++}END{
  print "www.books1.cn", array["www.books1.cn"]
  print "www.baidu.com", array["www.baidu.com"]
  print "www.qq.com", array["www.qq.com"]
}' books1.txt
awk -F '/' '{hotel[$3]++}END{for(domain in hotel)print domain,hotel[domain]}' books1.txt

awk '$2 ~ /th/ {print $2,$4}' log.txt # 輸出包含 "th" 的第二列,并列印第二列與第四列
awk '/re/ ' log.txt # 輸出包含 re 的行
awk 'BEGIN{IGNORECASE=1} /this/' log.txt # 忽略大小寫
awk '!/th/ {print $2,$4}' log.txt # 在包含 th 的行中輸出第 2,4 列

awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test.txt # 統計空行數 
ls -l|awk 'BEGIN{sum=0} !/^d/{sum+=$5} END{print "total size is",sum}' # 計算檔案大小

route -n|awk 'NR!=1{print}' # 不顯示第一行

awk '!/mysql|mail/{print}' /etc/passwd
awk -F: '/mail/,/mysql/{print}' /etc/passwd # 區間比對

awk -F: '$1~/mail/{print $1}' /etc/passwd  # $1 比對指定内容才顯示
awk -F: '{if($1~/mail/) print $1}' /etc/passwd  # 與上面相同,if 必須用在 {} 中,且比較内容用 () 括起來
           

參考

https://www.cnblogs.com/forestwolf/p/6413916.html

http://www.runoob.com/linux/linux-comm-sed.html

http://www.runoob.com/linux/linux-comm-awk.html

https://www.cnblogs.com/xudong-bupt/p/3721210.html

繼續閱讀