shell腳本三劍客(grep,sed,awk)


1.grep詳解及用法

( 1 )grep (global search regular expression(RE) and print out the line,全面搜索正則表達式並把行打印出來),是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來。抓取、過濾、篩選,找文件的內容。

Unix的grep家族包括grep、egrep和fgrep。egrep和fgrep的命令只跟grep有很小不同。egrep是grep的擴展,支持更多的re元字符, fgrep就是fixed grep或fast grep,它們把所有的字母都看作單詞,也就是說,正則表達式中的元字符表示回其自身的字面意義,不再特殊。

linux使用GNU版本的grep。它功能更強,可以通過-G、-E、-F命令行選項來使用egrep和fgrep的功能。

參數

說明

-v

反轉查找、過濾

-n

顯示行號

-i

忽略大小寫

-E

=egrep

-a

在二進制中,以文本文件的方式搜索數據

-o

只輸出文件中匹配到的信息

-c

統計匹配的行數

( 2 ) grep 常見用法

          - n 過濾並顯示行號

     

 

 

         - v 排除某行

      

         - i 忽略大小寫

       

           - c 統計匹配的行數

       

 

 

   小試牛刀: 用grep+cut 取網卡的IP

       

 

 

 2. 經過上面的小題讓我們知道grep也不是萬能的所以我們就需要運用到第二個文件處理工具 sed 。

( 1 )sed的詳解及用法

 sed是一個很好的文件處理工具,本身是一個管道命令。能同時處理多個文件多行的內容,可以不對原文件改動,把整個文件匹配內容選取之后再輸入到  屏幕,可以把只匹配到模式的內容輸入到屏幕上。

 還可以對原文件內容行進行替換、刪除、新增等特定工作改動,但是不會再屏幕上返回結果。

 ( 2 )sed 命令參數

參數

說明

- i

修改內容

- n

取消默認輸出

- r

在腳本中支持擴展正則表達式

- e

一條語句可以執行多個sed命令

- h

也就是--help 顯示幫助 

( 2.1 ) sed標記參數(前面沒有 - 的參數),也可以稱之為編輯器

a∶	在定位行后新增內容, a 的后面可以接字符串,而這些字符串會在新的一行出現(當前行的下一行);
c∶	用新文本替換定位文本, c 的后面可以接字符串,這些字符串可以取代 n1,n2 之間的行;
d∶	刪除定位行,因為是刪除啊,所以 d 后面通常不接任何咚咚;
g∶	表示行內全面替換。 --global
i∶	在定位行前插入新內容, i 的后面可以接字符串,而這些字符串會在新的一行出現(當前行的上一行);
I∶	還是| 顯示與八進制ACSII代碼等價的控制符;
n∶	從另一個文件中讀文本下一行,並從下一條命令而不是第一條命令開始對其的處理;
N∶	在數據流中添加下一行以創建用於處理的多行組;
p∶	列印,亦即將某個選擇的資料印出。通常 p 會與參數 sed -n 一起運作;
q∶	第一個模式匹配完成后退出或立即退出;
r∶	后面接filename,表示從另一個文件中讀文本,類似輸入重定向 <
s∶	使用指定模式去替換匹配到模式,可以直接進行取代的工作!通常這個 s 的動作可以搭配正規表達式!例如 1,20s/old/new/g;
w∶	后面接filename,表示把行寫入一個文件;
x:	表示互換模板塊中的文本和緩沖區中的文本;
y:	表示把一個字符翻譯為另外的字符(但是不用於正則表達式)
=∶	表示打印行號;
{}∶	當用到sed不同的標記參數(就是前面沒有-的參數)時,用大括號{},且不同標記參數之間用分號隔開

   ( 3.1 ) 單行追加

 1 [root@ mysql-master ~]# cat test.txt
 2 I love linux.
 3 
 4 I like badminton ball ,billiard ball and chinese chess!
 5 my blog is http://blog.51cto.com
 6 our site is http://www.aaa.org
 7 my qq num is 49000448.
 8 
 9 ABVGSRGDRH
10 
11 not 4900000448.
12 my god!
13 
14 
15 
16 sed '2a thank you' test.txt      追加thank you 到test.txt第二行后(此法追加只是臨時顯示)
17 
18 sed -i '2a thank you' test.txt    永久改變文件前邊必須加參數-i

  ( 3.2 ) 多行追加

   sed '2a thank you\ngood' test.txt 追加thank you和good到test.txt第二行后(\n表示回車)   

   

 

 ( 4 )  刪除

 

 1 sed '2d' test.txt         刪除test.txt中的第二行
 2 
 3 sed '2,5d' test.txt     刪除test.txt第2行到第5行
 4 
 5 '3,$d'             刪除第3行到最后一行
 6 
 7 '1~2d'            刪除奇數行    
 8 
 9 '2~2d'            刪除偶數行
10 
11 '1,+2d'         刪除第1行+后邊兩行
12 
13 '/god/d'        刪除文件中包含god的行
14 
15 '1d;5d;7d'        刪除不規則行數

 

  ( 5.1 )按行替換

 

  sed '2c beautiful' test.txt  把test.txt文件中的第2行替換成beautiful

  

 

  ( 5.2 ) 文本替換

 's#A#B#g'=='s/A/B/g'   查找替換 把A替換為B

 sed -i 's/A/B/g' /data/ett.txt     查找A替換成B

 s:單獨使用→將每一行中第一處匹配的字符串進行替換 ==>sed命令 
 
 g:每一行進行全部替換 ==>sed命令s的替換標志之一,非sed命令 
 
 對比得出s前加數字針對某行,不加數字針對所有行;后邊加g是全部,加數字是某一處

sed -i '2s#1#3#2' emp.txt

第一個數字意思為:文件中的某行
第二個數字意思為:文件源字符
第三個數字意思為:文件修改后的字符
第四個數字意思為:文件中的某列

 

 小試牛刀:使用sed查看IP地址

 ip a show ens33|sed -n  '3s#.*inet##gp'|sed -n 's#/.*##gp'

 

 3 . awk 

( 3.1 )  awk簡介

awk其名稱得自於它的創始人 Alfred Aho 、Peter Weinberger 和 Brian Kernighan 姓氏的首個字母。實際上 AWK 的確擁有自己的語言: AWK 程序設計語言 , 三位創建者已將它正式定義為“樣式掃描和處理語言”。它允許您創建簡短的程序,這些程序讀取輸入文件、為數據排序、處理數據、對輸入執行計算以及生成報表,還有無數其他的功能。

awk 是一種很棒的語言,它適合文本處理和報表生成,其語法較為常見,借鑒了某些語言的一些精華,如 語言等。在 linux 系統日常處理工作中,發揮很重要的作用,掌握了 awk將會使你的工作變的高大上。 awk 是三劍客的老大,利劍出鞘,必會不同凡響。

 

awk是一個強大的文本分析工具,相對於grep的查找,sed的編輯,awk在其對數據分析並生成報告時,顯得尤為強大。簡單來說awk就是把文件逐行的讀入,以空格為默認分隔符將每行切片,切開的部分再進行各種分析處理。

使用方法   : awk '{pattern + action}' {filenames}

盡管操作可能會很復雜,但語法總是這樣,其中 pattern 表示 AWK 在數據中查找的內容,而 action 是在找到匹配內容時所執行的一系列命令。花括號({})不需要在程序中始終出現,但它們用於根據特定的模式對一系列指令進行分組。 pattern就是要表示的正則表達式,用斜杠括起來。

awk語言的最基本功能是在文件或者字符串中基於指定規則瀏覽和抽取信息,awk抽取信息后,才能進行其他文本操作。完整的awk腳本通常用來格式化文本文件中的信息。通常,awk是以文件的一行為處理單位的。awk每接收文件的一行,然后執行相應的命令,來處理文本。

 ( 3.2 )  awk 內置變量

ARGC               命令行參數個數
ARGV               命令行參數排列
ENVIRON            支持隊列中系統環境變量的使用
FILENAME           awk瀏覽的文件名
FNR                瀏覽文件的記錄數
FS                 設置輸入域分隔符,等價於命令行 -F選項
NF                 瀏覽記錄的域的個數
NR                 已讀的記錄數
OFS                輸出域分隔符
ORS                輸出記錄分隔符
RS                 控制記錄分隔符

$0變量是指整條記錄。$1表示當前行的第一個域,$2表示當前行的第二個域,......以此類推。

$NF是number finally,表示最后一列的信息,跟變量NF是有區別的,變量NF統計的是每行列的總數

( 3.3 ) awk 原理 

 通過一個簡短的命令 我們就可以理解其工作原理

 

[root@Gin scripts]# awk '{print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
.....................................................
 
[root@Gin scripts]# echo hhh|awk '{print "hello,world"}'
hello,world
 
[root@Gin scripts]# awk '{print "hiya"}' /etc/passwd
hiya
hiya
hiya
hiya
···················································

  

你將會見到/etc/passwd 文件的內容出現在眼前。現在,解釋 awk 做了些什么。調用 awk時,我們指定/etc/passwd 作為輸入文件。執行 awk 時,它依次對/etc/passwd 中的每一行執行 print 命令。

所有輸出都發送到 stdout,所得到的結果與執行 cat /etc/passwd 完全相同。
現在,解釋{ print }代碼塊。在 awk 中,花括號用於將幾塊代碼組合到一起,這一點類似於 語言。在代碼塊中只有一條 print 命令。在 awk 中,如果只出現 print 命令,那么將打印當前行的全部內容。
再次說明, awk 對輸入文件中的每一行都執行這個腳本。

  

 

  

1 $ awk -F":" '{ print $1 }' /etc/passwd
2 $ awk -F":" '{ print $1 $3 }' /etc/passwd
3 $ awk -F":" '{ print $1 " " $3 }' /etc/passwd
4 $ awk -F":" '{ print "username: " $1 "\t\tuid:" $3" }' /etc/passwd

-F 指定分隔符為冒號

1
2
3
4
5
6
7
8
[root@localhost ~] # awk -F ':' '{print $1,$2}' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown

 awk 常用變量

NF:表示最后一個字段

1
2
3
4
5
6
[root@localhost ~] # awk -F ':' '{print $NF}' /etc/passwd
/bin/bash
/sbin/nologin
/sbin/nologin
/sbin/nologin
/sbin/nologin

 $(NF-1):表示倒數第二個字段

1
2
3
4
5
6
[root@localhost ~] # awk -F ':' '{print $(NF-1)}' /etc/passwd
/root
/bin
/sbin
/var/adm
/var/spool/lpd

 NR:表示當前處理的是第幾行

 輸出第二行

1
2
[root@localhost ~] # awk -F ":" 'NR==2 {print}' /etc/passwd
bin:x:1:1:bin: /bin : /sbin/nologin

 

輸出第三行以后的行

1
2
3
4
5
[root@localhost ~] # awk -F ':' 'NR>3 {print}' /etc/passwd
adm:x:3:4:adm: /var/adm : /sbin/nologin
lp:x:4:7:lp: /var/spool/lpd : /sbin/nologin
sync :x:5:0: sync : /sbin : /bin/sync
shutdown :x:6:0: shutdown : /sbin : /sbin/shutdown

 

 awk 內置函數

toupper()用於將字符轉為大寫【t^ber】

1
2
3
4
5
6
[root@localhost ~] # awk -F ':' '{print toupper($1)}' /etc/passwd
ROOT
BIN
DAEMON
ADM
LP

 tolower()用於將字符串轉為小寫

1
2
3
4
5
6
[root@localhost ~] # awk -F ':' '{print toupper($1)}' /etc/passwd >/tmp/aa.txt
[root@localhost ~] # awk '{print tolower($1)}' /tmp/aa.txt
root
bin
daemon
adm

 

 awk 允許指定輸出條件,只輸出符合條件的行

打印包含root的行

1
2
3
[root@localhost ~] # awk '/root/ {print}' /etc/passwd
root:x:0:0:root: /root : /bin/bash
operator:x:11:0:operator: /root : /sbin/nologin

 輸出第一個字段等於指定值的行

1
2
[root@localhost ~] # awk -F ':' '$1=="root" {print}' /etc/passwd
root:x:0:0:root: /root : /bin/bash

 awk if else語句

假如$1==root 打印第一個字段,否則打印第二個字段

1
2
3
4
5
6
[root@localhost ~] # awk -F : '{if ($1=="root") print $1;else print $2}' /etc/passwd
root
x
x
x
x

 

 awk 高級用法BEGIN END

任何在BEGIN之后列出的操作(在{}內)將在Unix awk開始掃描輸入之前執行,而END之后列出的操作將在掃描完全部的輸入之后執行。

因此,通常使用BEGIN來顯示變量和預置(初始化)變量,使用END來輸出最終結果

數字求和

 

1
seq  10| awk  '{sum+=$0} END {print sum}'

 

 

 

 

1
2
3
4
5
6
7
8
9
例:累計銷售文件xs中的銷售金額(假設銷售金額在記錄的第三字段):
 
cat  sx
 
一:50件:200.00
 
二:60件:300.00
 
三:70件:400.00

 

1
2
3
4
5
6
7
8
[root@localhost ~] # awk 'BEGIN {FS=":";print "統計銷售金額";total=0} {print $3;total=total+$3;} END {printf "銷售金額總計: %.2f\n",total}' sx
統計銷售金額
200.00
 
300.00
 
400.00
銷售金額總計: 900.00

AWK 數組

awk可以使用關聯數組這種數據結構,索引可以是數字或字符串。

AWK關聯數 組也不需要提前聲明其大小,因為它在運行時可以自動的增大或減小。

定義數組,並且打印數組元素

1
awk  'BEGIN{a[0]="xiaohong";a[1]="xiaolan";print a[0]}'

 打印所有元素的下標(索引)

1
awk  'BEGIN{a[0]="xiaohong";a[1]="xiaolan";for (i in a)print i;}'

 

 

 統計訪問網站的ip地址的個數

 

1
2
3
4
5
6
7
8
9
10
11
12
[root@localhost ~] # awk '{count[$1]} END {for (i in count) print i}' /var/log/httpd/access_log  #打印下標
172.18.47.60
172.18.47.61
127.0.0.1
[root@localhost ~] # awk '{count[$1]++} END {for (i in count) print i}' /var/log/httpd/access_log
172.18.47.60
172.18.47.61
127.0.0.1
[root@localhost ~] # awk '{count[$1]++} END {for (i in count) print i,count[i]}' /var/log/httpd/access_log
172.18.47.60 1001
172.18.47.61 1001
127.0.0.1 1001

 

  小試牛刀:使用awk查看IP地址

 ip a show ens33|grep 'inet'|awk -F ' |/' 'NR==1{print $6}'


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM