Linux三大利器grep,sed,awk

一. grep和正則表達式

grep

grep(global search regular expression(RE) and print out the line,全面搜索正則表達式並把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來。php

選項

-d<進行動做> 當指定要查找的是目錄而非文件時,必須使用這項參數,不然grep命令將回報信息並中止動做。

-h 當搜索多個文件時,不顯示匹配文件名前綴

-i 忽略字符大小寫的差異。

-l 列出文件內容符合指定的範本樣式的文件名稱。

-n 列出全部的匹配的文本行,並顯示行號

-r  遞歸搜索,搜索當前目錄和子目錄,此參數的效果和指定「-d recurse」參數相同。

-v 反轉查找。只顯示不匹配的文本行

1. -r遞歸查找

root@siguorui-OptiPlex-7010:/home/xhprof/trunk# grep -r XHProfRuns_Default *
examples/sample.php:$xhprof_runs = new XHProfRuns_Default();
xhprof_html/callgraph.php:$xhprof_runs_impl = new XHProfRuns_Default();
xhprof_html/typeahead.php:$xhprof_runs_impl = new XHProfRuns_Default();

2. -I的使用,顯示文件名稱

root@siguorui-OptiPlex-7010:~# grep -I root abc.txt 123.txt passwd 
passwd:root:x:0:0:root:/root:/bin/bash

3. -n

root@siguorui-OptiPlex-7010:~# grep -n 'root' passwd 
1:root:x:0:0:root:/root:/bin/bash

正則表達式

1. 正則表達式單字符

  • 特定字符html

    • grep 'a' passwd
  • 範圍內字符mysql

    • grep '[a-z]' passwd
    • grep '[A-Za-z0-9]' passwd
    • grep '[^0-9]' passwd 取反,除去數字以外的字符
  • 任意字符linux

    • grep '.' passwd

可是在grep '[.]'中,.只是表明點這樣的字符,注意區別。若是要使用.的本意,採用\.的方式正則表達式

  • 以上三種組合

2. 正則表達式其餘符號

  • 邊界字符 頭尾字符sql

    • ^字符,頭字符,放在一串字母前邊,表明以此開頭。grep '^root' passwd
    • $符號,如false$,表明以false字符結束
    • ^$ 表明空行,grep '^$' passwd
  • 元字符mongodb

    • w:匹配任何字類字符,包括下劃線。至關於([A-Za-z0-9_])
    • W:大寫的W,匹配任何非字類字符。至關於([^A-Za-z0-9_])
    • b 表明單詞分隔。如,grep '\bx\b' passwd,能夠將單個先後分隔的x字符選出來,但不會選擇單詞中出現的x
  • 正則表達式字符組合shell

    • 重複express

      \* : 零次或屢次匹配前面的字符或子表達式。例子:grep 'se*' test.txt\
      \+ : 一次或屢次匹配前面的字符或表達式.例子:grep 'se\+' test.txt.注意這裏加號前面要加反斜槓
      ? : 零次或一次匹配前面的字符或表達式.如:grep 'se\?' test.txt.注意?前面也要加反斜槓
      括號的使用 :grep '\(se\)*' test.txt。注意括號前面要加反斜槓
      指定重複次數 : grep '[0-9]\{2,3\}' passwd

二.sed 行編輯器

sed是一種流編輯器,它是文本處理中很是重要的工具,可以完美的配合正則表達式使用,功能不一樣凡響。處理時,把當前處理的行存儲在臨時緩衝區中,稱爲「模式空間」(pattern space),接着用sed命令處理緩衝區中的內容,處理完成後,把緩衝區的內容送往屏幕。接着處理下一行,這樣不斷重複,直到文件末尾。文件內容並無 改變,除非你使用重定向存儲輸出。Sed主要用來自動編輯一個或多個文件;簡化對文件的反覆操做;編寫轉換程序等。數組

命令格式

sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

options經常使用選項

-e<script>或--expression=<script>:以選項中的指定的script來處理輸入的文本文件;

-n或--quiet或——silent:僅顯示script處理後的結果;

command經常使用

a\ 在當前行下面插入文本。
i\ 在當前行上面插入文本。
c\ 把選定的行改成新的文本。
d 刪除,刪除選擇的行。
n 讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令。
s 替換指定字符
p 打印模板塊的行。
q 退出Sed。
r file 從file中讀行。
w file 寫並追加模板塊到file末尾。

1. p 打印相關的行

nl passwd|sed -n '10p' //打印第10行內容
sed -n 'p' passwd
sed -n '/root/p' passwd //正則匹配打印
nl passwd|sed -n '10,20p' //打印第10行到20行
nl passwd|sed -n '/news/,/nobody/p' //用正則來指定一個行的範圍
nl passwd|sed -n '10,20!p'  //不選擇10到20行,!表明取反
nl passwd|sed -n '1~2p' //間隔行,會輸出1,3,5....行

注意,這裏必定要加上-n選項,不然每條數據會顯示一樣的2行。而且無關的其餘內容也會顯示出來

2. a 在行後面增長內容

root@siguorui-OptiPlex-7010:~# nl passwd|sed '2a **************'
     1    root:x:0:0:root:/root:/bin/bash
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
**************
     3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
     
nl passwd|sed '1,2a **************' //在範圍內的每一行後面都插入

3. i在行前面插入

root@siguorui-OptiPlex-7010:~# nl passwd|sed '1,2i **************'
**************
     1    root:x:0:0:root:/root:/bin/bash
**************
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin

4. c把選定的行改成新的文本

root@siguorui-OptiPlex-7010:~# nl passwd|sed '1c abcd'
abcd
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
     
 //與a,i不一樣的時,若是這裏是一個行的範圍則是把這個範圍內容替換爲當前內容   
root@siguorui-OptiPlex-7010:~# nl passwd|sed '1,3c abcd'
abcd
     4    sys:x:3:3:sys:/dev:/usr/sbin/nologin

5. d刪除行

root@siguorui-OptiPlex-7010:~# nl passwd | sed '/root/d'
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
     3    bin:x:2:2:bin:/bin:/usr/sbin/nologin

應用案例

在文件的末尾插入2行
nl passwd | sed '$a \    abcd \n    linux'

    49    memcache:x:126:132:Memcached,,,:/nonexistent:/bin/false
    50    postfix:x:127:133::/var/spool/postfix:/bin/false
    51    mongodb:x:128:65534::/var/lib/mongodb:/bin/false
    abcd 
    linux
    
    
    刪除文件中的空行,^$直接相連表明空行
    nl passwd | sed '/^$/d'

6. s替換命令

sed 's/false/true/' passwd 
輸出:
...
sphinxsearch:x:124:131::/home/sphinxsearch:/bin/true
sshd:x:125:65534::/var/run/sshd:/usr/sbin/nologin
memcache:x:126:132:Memcached,,,:/nonexistent:/bin/true
postfix:x:127:133::/var/spool/postfix:/bin/true

sed 's/:/%/g' passwd  //加g全局替換
輸出:
sphinxsearch%x%124%131%%/home/sphinxsearch%/bin/false
sshd%x%125%65534%%/var/run/sshd%/usr/sbin/nologin
memcache%x%126%132%Memcached,,,%/nonexistent%/bin/false
postfix%x%127%133%%/var/spool/postfix%/bin/false

過濾ifconfig中的ip

eno1      Link encap:以太網  硬件地址 f8:b1:56:c5:e7:44  
          inet 地址:172.19.5.175  廣播:172.19.5.255  掩碼:255.255.255.0
          inet6 地址: fe80::c422:e82d:ad66:7a92/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  躍點數:1
          接收數據包:35171885 錯誤:53864 丟棄:0 過載:0 幀數:29047
          發送數據包:25049325 錯誤:0 丟棄:0 過載:0 載波:0
          碰撞:0 發送隊列長度:1000 
          接收字節:8124495140 (8.1 GB)  發送字節:4549284803 (4.5 GB)
          中斷:20 Memory:f7f00000-f7f20000 

 ifconfig eno1 | sed -n '/inet /p'|sed 's/inet.*地址://'|sed 's/廣播.*$//'
 
 輸出:
 172.19.5.175

高級操做命令

1. 多個sed命令,用{}包住,‘;’隔開

刪除44-48行內容,而後將false替換爲true
nl passwd|sed '{44,48d;s/false/true/}'

    41    statd:x:121:65534::/var/lib/nfs:/bin/true
    42    mysql:x:1001:1001::/home/mysql:/sbin/nologin
    43    www:x:1002:1002::/home/www:/sbin/nologin
    49    memcache:x:126:132:Memcached,,,:/nonexistent:/bin/true
    50    postfix:x:127:133::/var/spool/postfix:/bin/true
    51    mongodb:x:128:65534::/var/lib/mongodb:/bin/true

2. n 讀取下一個輸入行

//n的用法
root@siguorui-OptiPlex-7010:~# nl passwd|sed -n '{p;n}'
     1    root:x:0:0:root:/root:/bin/bash
     3    bin:x:2:2:bin:/bin:/usr/sbin/nologin
     5    sync:x:4:65534:sync:/bin:/bin/sync
     7    man:x:6:12:man:/var/cache/man:/usr/sbin/nologin

提示: nl passwd|sed -n '{1~2p}'  前面講到的,~也能夠實現一樣的效果

3. &替換固定字符串,&表明前面匹配到的字符

//姓名和後面的內容加空格隔開
root@siguorui-OptiPlex-7010:~# sed 's/^[a-z_]\+/&     /' passwd
root     :x:0:0:root:/root:/bin/bash
daemon     :x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin     :x:2:2:bin:/bin:/usr/sbin/nologin


//用戶名的首字母轉換爲大寫
//元字符\u \l(對首字母大小寫轉換) \U \L(對一串字符大小寫轉換),轉換爲大寫小寫字符

//小寫u,替換用戶名首字母
root@siguorui-OptiPlex-7010:~# sed 's/^[a-z_]\+/\u&/' passwd
Root:x:0:0:root:/root:/bin/bash
Daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
Bin:x:2:2:bin:/bin:/usr/sbin/nologin

//大寫U,用戶名所有替換爲大寫
root@siguorui-OptiPlex-7010:~# sed 's/^[a-z_]\+/\U&/' passwd
ROOT:x:0:0:root:/root:/bin/bash
DAEMON:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
BIN:x:2:2:bin:/bin:/usr/sbin/nologin

4. ()的使用

//從passwd文件中,提取出username,uid,gid.  \1,\2,\3表明前面()匹配到字符
root@siguorui-OptiPlex-7010:~# sed 's/\(^[a-z_-]\+\):x:\([0-9]\+\):\([0-9]\+\):.*$/USER:\1    UID:\2   GID:\3/' passwd
USER:root    UID:0   GID:0
USER:daemon    UID:1   GID:1
USER:bin    UID:2   GID:2
USER:sys    UID:3   GID:3
USER:sync    UID:4   GID:65534

5. -r複製指定文件插入到匹配行。-w複製匹配行拷貝到指定文件

//123.txt文件中有3行,全是數字。abc.txt文件中有3行,全是字母
//下面命令的實現結果,讀取123.txt的內容,複製到匹配的abc.txt文件的第一行,文件內容均不改變
root@siguorui-OptiPlex-7010:~# sed '1r 123.txt' abc.txt 
qwefadssa
1232323223
32343434
23333
trwrda
asdfasdf

//下面命令的實現結果,匹配abc.txt文件的第二行,寫入到123.txt文件中。123.txt文件會發生變化,abc.txt文件內容不變
root@siguorui-OptiPlex-7010:~# sed '2w 123.txt' abc.txt 
qwefadssa
trwrda
asdfasdf
root@siguorui-OptiPlex-7010:~# cat 123.txt 
trwrda


//總結
sed '2w或2r 文件A' 文件B
匹配的文件都是針對文件B來講的,讀或寫都是針對文件A來講的

6. q找到指定結果後就提早退出

root@siguorui-OptiPlex-7010:~# nl passwd |sed '2q'
     1    root:x:0:0:root:/root:/bin/bash
     2    daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
root@siguorui-OptiPlex-7010:~# nl passwd |sed '/root/q'
     1    root:x:0:0:root:/root:/bin/bash
root@siguorui-OptiPlex-7010:~#

七、sed 批量替換多個文件內容

加-i參數,文件的內容會被真正改變,若是不加則只是輸出替換後的結果,文件內容並未改變
格式: sed -i "s/查找字段/替換字段/g"   `grep 查找字段 -rl 路徑`
例:sed -i "s/oldstring/newstring/g" `grep oldstring -rl yourdir`
         sed -i "s/English/China/"  `ls test*`

3、awk

AWK是一種處理文本文件的語言,是一個強大的文本分析工具。特色是處理靈活,功能強大。可實現統計、製表以及其餘功能。

之因此叫AWK是由於其取了三位創始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的Family Name的首字符。

格式

  • 命令行格式
    awk [options] 'command' file(s)
  • 腳本格式
    awk -f awk-script-file file(s)

命令形式:

awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
  • [-F|-f|-v] 大參數,-F指定分隔符,-f調用腳本,-v定義變量 var=value

' ' 引用代碼塊

  • BEGIN 初始化代碼塊,在對每一行進行處理以前,初始化代碼,主要是引用全局變量,設置FS分隔符
  • // 匹配代碼塊,能夠是字符串或正則表達式
  • {} 命令代碼塊,包含一條或多條命令
  • ; 多條命令使用分號分隔
  • END 結尾代碼塊,在對每一行進行處理以後再執行的代碼塊,主要是進行最終計算或輸出結尾摘要信息

經常使用內置參數

  • $0,$1,$2... 表示整個當前行
  • $1 每行第一個字段
  • NF 字段數量變量
  • NR 每行的記錄號,多文件記錄遞增
  • FILENAME 文件名

1. 經常使用內置參數,$1,$2....。經過分隔符指定,按順序依次爲$1,$2...。默認分隔符爲空格

awk -F ':' '{print "USERNAE:"$1"\t""UID:"$3}' passwd

2. NR,NF,FILENAME

awk -F ':' '{print "Line:"NR,"Col:"NF,"USER:"$1}' passwd

3. 運用printf指定格式來打印

awk -F ':' '{printf("Line:%3s Col:%s User:%s\n",NR,NF,$1)}' passwd

root@siguorui-OptiPlex-7010:~# awk -F ':' '{printf("Line:%3s Col:%s User:%s\n",NR,NF,$1)}' passwd
Line:  1 Col:7 User:root
Line:  2 Col:7 User:daemon
Line:  3 Col:7 User:bin
Line:  4 Col:7 User:sys
...

4. 使用if

awk -F ':' '{if ($3>100) printf("Line:%3s Col:%s User:%s\n",NR,NF,$1)}' passwd

5. 正則和命令結合使用

awk -F ':' '/root/{print $1}' passwd

root@siguorui-OptiPlex-7010:~# awk -F ':' '/root/{print $1}' passwd
root

6. 使用BEGIN和END來製表

awk -F ':' 'BEGIN{print "line  col   user"}{print NR" |"NF" |"$1}END{print "----------------"FILENAME}' passwd

7. 使用BEGIN和END來統計一個目錄下文件總計大小

ls -l|awk 'BEGIN{size=0}{size+=$5}END{print " size is "size/1024/1024"M"}'

8. 統計passwd中不爲空的行數。$1!~,~表明匹配後面的正則,!~表明不匹配。/^$/正則匹配空行

awk -F ':' 'BEGIN{count=0}$1!~/^$/{count++}END{print " count ="count}' passwd

9. 統計結果放到數組中,並打印輸出

awk -F ':' 'BEGIN{count=0}{if ($3>100) name[count++]=$1}END{for(i=0;i<count;i++) print i,name[i]}' passwd 

root@siguorui-OptiPlex-7010:~# awk -F ':' 'BEGIN{count=0}{if ($3>100) name[count++]=$1}END{for(i=0;i<count;i++) print i,name[i]}' passwd 
0 nobody
1 systemd-network
2 systemd-resolve
3 systemd-bus-proxy
4 syslog

十、計算總成績和平均成績

test的內容

zhangsan 80
lisi 81.5
wangwu 93
zhangsan 85
lisi 88
wangwu 97
zhangsan 90
lisi 92
wangwu 88

要求輸出格式:(average:平均成績,total:總成績)
name#######average#######total
zhangsan xxx xxx
lisi xxx xxx
wangwu xxx xxx

awk 'BEGIN{print "name####average#####total"}{score[$1]+=$2;count[$1]+=1}END{for (i in score) print i,score[i]/count[i],score[i]}' test.txt

圖片描述
該題提供了一種新的遍歷數組的方式,for (x in 數組)

參考:

相關文章
相關標籤/搜索