RH254-第二十八節-腳本這sed,awk,grep(二)

Linux查找命令:grep,awk,sed

grep

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

一般格式:

 grep [選項] 基本正則表達式 [文件]

選項

    -c    只輸出匹配行的計數
    -i    不區分大小寫(單字符)
    -h    不顯示文件名(多文件時)
    -l    只輸出文件名(多文件時)
    -n    顯示匹配行及行號
    -s    不顯示錯誤信息
    -v    顯示不包含匹配文本的所有行

    --color=auto 自動高亮找到的關鍵詞

示例
1) 將/etc/passwd,有出現 root 的行取出來:

$ grep 'root' /etc/passwd

root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

# 或者
$ cat /etc/passwd | grep 'root'

2)將/etc/passwd,有出現 root 的行取出來,同時顯示這些行在/etc/passwd的行號:

$ grep -n root /etc/passwd

1:root:x:0:0:root:/root:/bin/bash
30:operator:x:11:0:operator:/root:/sbin/nologin

3)將/etc/passwd,將沒有出現 root 的行取出來

$ grep -v root /etc/passwd

root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

4)將/etc/passwd,將沒有出現 root 和nologin的行取出來

$ grep -v root /etc/passwd | grep -v nologin

root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

5) 查找nginx是否運行:

$ ps aux | grep nginx

www       1576  0.0  2.7  71652 28232 ?        S    Aug14   0:21 nginx: worker process

根據文件內容遞歸查找目錄

6)在當前目錄裏文件查找字符串'math'

$ grep 'math' *

grep: my: Is a directory
grep: my1: Is a directory
s.txt:lisi 1989 male math 99
s.txt:wangxuebing 1978 male math 89
s.txt:lichang 1989 male math 99

7)在當前目錄及其子目錄下搜索'math'行的文件

$ grep -r 'math' * 

8)當前目錄及其子目錄下搜索'math'行的文件,但是不顯示匹配的行,只顯示匹配的文件

$ grep -l -r 'math' * 

s.txt

正則表達式

支持正則語法,單引號裏面寫正則。

正則示例:

't[ae]st' #查找test或者tast
'[^g]oo' #字符串不含有g。注意中括號裏是不包含,不是以其開頭
'[^a-z]oo' #字符串前不包含a-z小寫字母
'[0-9]' #包含數字0-9
'^the' #匹配字母t開始的字符
'the$' #匹配字母e結尾的字符

示例:

$ grep '^xu' s.txt 

xuliang 1977 male economic 89
xuxin 1986 female english 99

更多的正則知識請查看正在相關知識。

擴展grep(grep -E 或者 egrep)

使用擴展grep的主要好處是增加了額外的正則表達式元字符集。

示例:

查找包含1990和1989的行:

$ grep -E '1990|1989' s.txt 

lisi 1989 male math 99
wanglijiang 1990 female chinese 78
lichang 1989 male math 99
wanglijiang 1990 female chinese 78
lisibao 1989 male math 99
xiaobao 1990 female chinese 78

awk

awk簡介

awk是一個強大的文本分析工具,相對於grep的查找,sed的編輯,awk在其對數據分析並生成報告時,顯得尤爲強大。簡單來說awk就是把文件(或其他方式的輸入流, 如重定向輸入)逐行的讀入(看作一個記錄集), 把每一行看作一條記錄,以空格(或\t,或用戶自己指定的分隔符)爲默認分隔符將每行切片(類似字段),切開的部分再進行各種分析處理。

awk有3個不同版本: awk、nawk和gawk,未作特別說明,一般指gawk,gawk 是 AWK 的 GNU 版本。

Awk基本語法: 

awk 'pattern1 {command1;command 2…; command 3}  pattern2 { command …}'

pattern表示用來過濾記錄的模式,可是是正則表達式,關係運算表達式,也可以什麼也沒有(表示選中所有記錄)。

每個pattern選中的行記錄會被花括號括起來的命令command操作一遍, command之間用;分割。 花括號裏面可以什麼也沒有, 則默認爲print輸出整行記錄。 Comamnd可以是輸出, 可以是算術運算,邏輯運算,循環控制等等。

示例

s.txt

zhangsan 1977 male computer 83
lisi 1989 male math 99
wanglijiang 1990 female chinese 78
xuliang 1977 male economic 89
xuxin 1986 female english 99
wangxuebing 1978 male math 89
lichang 1989 male math 99
wanglijiang 1990 female chinese 78
zhangsansan 1977 male computer 83 
langxuebing 1978 male math 89
lisibao 1989 male math 99
xiaobao 1990 female chinese 78

一行中的5個字段分辨表示姓名, 出生年, 性別,科目,分數, 是一個很傳統很典型的報表文件。

現在演示awk是如何查找的:

1)直接輸出1990年出生的同學:

$ awk '/1990/' s.txt

wanglijiang 1990 female chinese 78
wanglijiang 1990 female chinese 78
xiaobao 1990 female chinese 78
 

或者:

$ awk '/1990/{print $0}' s.txt

$0表示匹配所有列。

2)對chinese的課程的行輸出"語文":

$ awk '/chinese/{print "語文"}' s.txt

語文
語文
語文

3)記錄的頭部和結尾加上一段說明:

$ awk 'BEGIN{print "Result of the quiz:\n"}{print $0}END{print "------"}' s.txt
Result of the quiz:

zhangsan 1977 male computer 83
lisi 1989 male math 99
wanglijiang 1990 female chinese 78
xuliang 1977 male economic 89
xuxin 1986 female english 99
wangxuebing 1978 male math 89
lichang 1989 male math 99
wanglijiang 1990 female chinese 78
zhangsansan 1977 male computer 83
langxuebing 1978 male math 89
lisibao 1989 male math 99
xiaobao 1990 female chinese 78
------

4)查找女生的成績且只輸出姓名、學科、成績:

$ awk '$3=="female"{print $1,$4,$5}' s.txt
wanglijiang chinese 78
xuxin english 99
wanglijiang chinese 78
xiaobao chinese 78

$1表示第1列,$n類推。這裏條件是表達式,而不是正則。print裏,表示空格分隔符。

5)找出1990年出生的學生姓名,並要求匹配正則:

$ awk '$2~/1990/{print $1}' s.txt
wanglijiang
wanglijiang
xiaobao

這裏~表示匹配正則表達式。!~表示不匹配正則表達式。

6) 找出大於1985年出生的學生姓名,年齡,使用表達式:

$ awk '$2>"1985"{print $1,$2}' s.txt
lisi 1989
wanglijiang 1990
xuxin 1986
lichang 1989
wanglijiang 1990
lisibao 1989
xiaobao 1990

awk內置變量

awk有許多內置變量用來設置環境信息,這些變量可以被改變,下面給出了最常用的一些變量。

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

$0                 指整條記錄
$1, $2, … $n      當前記錄的字段

示例:
6)第四個字段科目爲chinese的記錄編號, 學生姓名, 科目:

$ awk '$4=="chinese"{print NR, $1, $4, $5}' s.txt

3 wanglijiang chinese 78
8 wanglijiang chinese 78
12 xiaobao chinese 78

7)統計數學成績大於90的個數:

$ awk 'BEGIN{goodMath=0;}($4=="math" && $5>90){goodMath++}END{print goodMath}' s.txt

3

8)顯示最近登錄的5個帳號

$ last -n 5 | awk  '{print $1}'
root
root
root
dmtsai
root

9)更換行分隔符爲;

$ cat /etc/passwd |awk  -F ':'  '{print $1}'  
root
daemon
bin
sys

-F指定域分隔符爲:

10)批量操作

# 關閉所有正在運行容器
docker ps | awk  '{print $1}' | xargs docker stop

# 刪除所有容器應用
docker ps -a | awk  '{print $1}' | xargs docker rm

sed

和grep、awk不同,sed更側重對搜索文本的處理,如修改、刪除、替換等等。

sed主要用來自動編輯一個或多個文件;簡化對文件的反覆操作;編寫轉換程序等。

語法

sed [-hnV][-e<script>][-f<script文件>][文本文件]

參數說明:

-e<script>或--expression=<script>     以選項中指定的script來處理輸入的文本文件。
-f<script文件>或--file=<script文件>     以選項中指定的script文件來處理輸入的文本文件。
-h或--help 顯示幫助。
-n或--quiet或--silent 僅顯示script處理後的結果。
-i  直接編輯文件而不是顯示在屏幕上
-V或--version 顯示版本信息。

動作說明:

a :新增, a 的後面可以接字串,而這些字串會在新的一行出現(目前的下一行)~
c :取代, c 的後面可以接字串,這些字串可以取代 n1,n2 之間的行!
d :刪除,因爲是刪除啊,所以 d 後面通常不接任何咚咚;
i :插入, i 的後面可以接字串,而這些字串會在新的一行出現(目前的上一行);
p :列印,亦即將某個選擇的數據印出。通常 p 會與參數 sed -n 一起運行~
s :取代,可以直接進行取代的工作哩!通常這個 s 的動作可以搭配正規表示法!例如 1,20s/old/new/g 就是啦!

sed命令必須跟一個動作。

新建文件t.txt:

zhangsan 1977 male computer 83
lisi 1989 male math 99
wanglijiang 1990 female chinese 78

1)新增一行:第3行後新增:

$ sed -e '3a newline'

zhangsan 1977 male computer 83
lisi 1989 male math 99
wanglijiang 1990 female chinese 78
newline

2)插入一行:第3行前插入:

$ sed -e '3i newline'

zhangsan 1977 male computer 83
lisi 1989 male math 99
newline
wanglijiang 1990 female chinese 78

3)刪除一行:刪除第3行:

$ sed -e '3d'

zhangsan 1977 male computer 83
lisi 1989 male math 99

4)替換一行:

$ sed -e '3c newline'

zhangsan 1977 male computer 83
lisi 1989 male math 99
newline

5)行內部分內容的替換:
格式:

sed 's/要被取代的字串/新的字串/g'

示例:

$ sed '3s/1990/2000/g' t.log 

zhangsan 1977 male computer 83
lisi 1989 male math 99
wanglijiang 2000 female chinese 78

6)多行操作:

$ sed '2,3d' t.log  #刪除2,3行
$ sed '2,$d' t.log  #從第2行開始刪除到末尾
$ sed '2,3a test' t.log #分別在第2行,第3行增加字符"test"

注意:
1、上述的操作均只在輸出緩衝裏操作,文件並沒有變化;需要直接修改文件,前面加-i參數;
2、-e參數可以沒有。

Xargs

之所以能用到這個命令,關鍵是由於很多命令不支持|管道來傳遞參數,而日常工作中有有這個必要,所以就有了xargs命令,例如:

find /sbin -perm +700 |ls -l       #這個命令是錯誤的
find /sbin -perm +700 |xargs ls -l   #這樣纔是正確的
發佈了66 篇原創文章 · 獲贊 25 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章