Linux三劍客

下載排好版的word文檔,點這裏

awk

awk推薦去看朱雙印的博客“awk從放棄到入門”,寫的真的很好,本文的awk就總結於它。

 

awk其實是一門編程語音,它支持條件判斷、數組、循環等功能。所以,我們也可以把awk理解成一個腳本語言解釋器

1awk基礎

1.1、普通模式

awk option ‘program’ file1file2

image.png

1.2、特殊模式

image.png

1)  BEGIN和END模塊只能有一個。中間的pattern匹配,可以有多個

NR==2{print $1}NR==5{print $1}

2)  BEGIN模塊,代表awk在處理文本前要做的事。即使不接收文件名,僅僅使用BEGIN模塊打印,也能正常輸出

awk ‘BEGIN {print “111”,”222”}’

3)  END模塊,代表awk在處理文本後要做的事

awk ‘{print $1,$2} END{print ‘333’,’444’}’test

1.3、內置變量

變量名

屬性

備註

$0

當前記錄。即一整行


$1~$n

當前記錄的第n個字段

awk   ‘{print “str:”$1}’

FS

輸入字段分隔符,默認space

awk   –F ‘:’

awk   –v FS=’:’

RS

輸入記錄分隔符,默認爲\n

如果RS=””,會以空白行分隔

OFS

輸出字段分隔符,默認space


ORS

輸出的記錄分隔符,默認\n


NF

當前記錄中的字段個數,即多少列


NR

行號,從1開始


FNR

各文件分別顯示行號


FILENAME

當前文件名

awk   ‘{print FILENAME,$0}’

ARGC

命令行參數的個數


ARGV

數組,保存的是命令行所給定的參數

ARGV[0]awk,單引號中的不算參數,處理的文件是參數

image.png

1.4、自定義變量

awk除了使用內置變量,還可以自己定義變量。

方法一:-v varname=value 變量名區分字符大小寫。-v:設置變量

方法二:在program中定義

1-v 定義

image.png


2、在program定義

image.png


2printf

awk本身負責文本切割,printf動作則負責格式格式化文本。在瞭解awkprintf動作前,需要首先了解printf命令

2.1shellprintf命令

shell中,echoprintf都是輸出文本的命令。echo輸出的字符串,會自動在末尾加上\n

printf不會。printf的作用是按照我們指定的格式輸出文本,所以\n,也需要我們自己指定

echoprintf

image.png

注意看3printf的優勢就在於,可以用格式替換符,幫我們處理一長串的str

 

替換符號

格式替換符

名稱

含義

%s

字符串

%f

浮點格式

%b

對應的參數包含轉義字符時,對應的轉義字符會被轉義

%c

ASCII字符,顯示對應參數的第一個字符

%d%i

十進制整數

%o

不帶正負號的八進制值

%u

不帶正負號的十進制值

%x

不帶正負號的十六進制值,用af表示1015

%X

不帶正負號的十六進制值,用AF表示1015

%%

表示‘%’本身

 

轉義字符

名稱

含義

\a

警告字符,常爲ASCIIBEL字符

\b

後退

\c

不顯示輸出結果中任何結尾的換行字符(%b格式下的參數字符串依然有效)

\f

換頁(formfeed

\n

換行

\r

回車

\t

水平製表符

\v

垂直製表符

\\

\”本身

\ddd

表示13位數八進制值得字符串,僅在字符格式串中有效

\0ddd

表示13位數八進制值得字符串

 

修飾符

參數

含義

%7s

7就代表當前替換符對應的輸出長度爲7個字符寬,不足補齊,超出也正常顯示

%-7s

-”,表示左對齊,不加時,是右對齊

%+5d

正數會自動變爲+num

%12.3f

.3”表示保留小數點後三位,%f默認是小數點後6

%12.5d

.5”表示整數的長度,不足用0補齊

 

 

例子
image.png

2.2awkprintf動作

awkprintf動作與shellprintf命令很像,只是要注意幾點:

1)  使用printf動作輸出的文本不會換行,要自己手動加\n

2)  使用printf動作時,“指定的格式”與“被格式化的文本”間,要用“逗號”隔開

3)  使用printf動作,“格式替換符”與“被格式化的文本”數量一一對應

例子

image.png

awk -v FS=':' 'BEGIN{printf "%-10s\t %s\n","用戶名稱","用戶ID"} {printf "%-10s\t %s\n",$1,$3}' /etc/passwd

用戶名稱         用戶ID

root             0

bin              1

3awk模式(Pattern

3.1grepawk的正則對比

grep ‘^root’/etc/passwd

awk ‘/^root/{print $0}’ /etc/passwd

image.png

image.png

 

3.2awk正則的注意點

1awk命令中的正則是“擴展正則表達式”

2)當使用{x,y}[[:space]],這種正則時,要加上參數—posix

3)注意對“\”和“.”轉義

 

3.3awk的行範圍模式

image.png

兩個正則的就是行範圍模式,從正則1匹配的行開始,到正則2匹配的行結束

正則匹配符

~

匹配後面的正則。’$1~/pattern/’

!~

不匹配後面的正則’$1!~/pattern/’

 

3.4、例子



image.png



4awk動作總結

4.0、動作拆分

image.png

 

上圖的動作分爲兩個部分:

1)  紅線標註:最外側的括號“{}”。“組合語句”類型的動作,將多個代碼組合成代碼塊

2)  藍線標註:“print $0”。print是“輸出語句”類型的動作

例子


image.png

4.1if動作

image.png

如果if對應的{},只有一條命令,可以省略{}

4.2for動作

image.png

4.3while動作


image.png

4.4do…while動作

do…while循環無論是否滿足while的條件,都會先執行一次do裏的命令

# 打印一遍test

image.png

# 打印5遍test

image.png

4.5cotinuebreak

# 1~5,不打印3

image.png

# 打印1~3

image.png

4.6exit

awk中,exit表示跳過後序所有動作,直接執行END內的命令。如果沒有END模式,則會直接結束awk命令

# 只打印1

image.png

# 不會打印$0

image.png

4.7next

next的作用是跳過當前行。直接從下一行 開始處理

# 跳過第2行

image.png

 

5awk數組

5.1、基礎概念

1awk中的數組是一個使用字符串作爲下標的“關聯數組”。

2)我們在使用時,可以用 數字/字符串 作爲下標,不過使用數字作爲下標時,awk默認會把“數字”下標轉換爲“字符串”。

3)在awk中,元素的值可以設置爲“空”。

4當一個元素不存在於數組時,如果我們直接引用這個不存在的元素,awk會自動創建這個元素,並且默認爲這個元素賦值爲“空字符串”

5)在awk中,判斷數組中元素是否存在,用“if(下標 in 數組名)”。即判斷數組中是否有key

6)使用split函數生成的數組,下標默認是從1開始的

5.2、基本操作

# 創建數組,直接創建就可以

image.png

# 刪除數組中的元素

awk ‘BEGIN{ …;delete huluwa[0]}’

# 刪除整個數組

awk ‘BEGIN{ …;delete huluwa}’

# for循環有序遍歷數組。只有下標是數字時,通過下標的遞增,纔能有序遍歷

awk ‘BEGIN{ …;for (i=1;i<=3;i++){print i,huluwa[i];} }’

# for循環無序遍歷數組。因爲awk數組本身是無序的關聯數組

awk ‘BEGIN{ …;for (i in huluwa){print i,huluwa[i]} }’

# 實例應用——統計某文件$1 重複出現的次數

awk ‘{count[$1]++} END{ for (i in count ) {print i,count[i]} }’ file

 

# 實例應用——統計某文本人名出現次數

awk ‘{ for (i=1;i<=NF;i++) {count[$i]++} } END{ for (a in count) {print a,count[a]} }

 

6awk內置函數

6.1、算術函數

rand函數,srand函數,int函數

rand函數固定打印了0.237788srand函數固定打印1,兩者合用,可生成小於1的隨機數

# rand函數

awk 'BEGIN{print rand()}'

0.237788

# srand函數

awk 'BEGIN{print srand()}'

1

# 生成小於1的隨機數

awk 'BEGIN{srand();print rand()}'         

0.319498

# 通過隨機數乘100,在通過int函數取整,生成0~100間的隨機數

awk 'BEGIN{srand();print int(100*rand())}'

76

 

6.2、字符串函數

gsub函數,sub函數

這兩個函數用於替換某些 文本

awk ‘{ gsub (“old”,“new”,$1);print $0}’file

awk ‘{ gsub (“[a-z]”,“new”,$1);print $0}’file

gsub將指定範圍內匹配的字符全部替換爲新字符

sub用法與gsub一樣,但只替換匹配範圍內第一次匹配到的字符

# 比如某文件就一行,$1=aaa。

gsub(“a”,“b”),則$1=bbb。第三個參數不加,則默認爲$0

sub(“a”,“b”),則$1=baa。

length函數

length函數可獲取指定字符串的長度。不指定參數,默認爲$0

awk ‘{ for (i=1;i<=NF;i++) {print $i,length($i)} }’file

index函數

獲取指定字符串位於整個字符串中的位置

awk ‘{print index($0,“LEE”)}’file

0

7

0

index函數在每一行中查找LEE,如果該行沒有,返回0,該行有,返回位置

split函數

split函數可以切割字符串,幫我們動態生成數組。生成的數組下標從1開始

# 將ts以“;”分隔,並將分隔後的str保存到huluwa數組中

awk –v ts=”one;two;three”‘BEGIN{ print split(ts,huluwa,”;”)}’

# split函數的返回值就是數組長度

split(ts,huluwa,”;”) == 3

6.3、排序函數

asort函數

asort函數根據數組的value值進行排序

# asort排序後,原有key將被數字替代

awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35 ; asort(t) ; for (i in t){print i,t[i]} }'

1 35

2 66

3 88

# asort排序時,新建一個數組。t[]不變,新創了new[]

awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35 ; asort(t,new) ; \

for (i in new){print i,new[i]} }'

# asort函數的返回值就是數組的長度

asort(t,new)==3

asorti函數

asorti函數會對原數組的key排序,然後將key作爲value生成一個新數組

awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35;asorti(t,new);for (i in new){print i,new[i]} }' 

1 a

2 b

3 c

# 通過asorti排列原數組

awk 'BEGIN{ t["a"]=66;t["b"]=88;t["c"]=35;asorti(t,new);\

for (i in new){print i,new[i],t[new[i]] } }'

1 a 66

2 b 88

3 c 35

 

 

7、三元運算與打印奇偶行

7.1、三元運算

# if…else判斷用戶類型

awk –F : ‘{ if($3<500){usertype=“系統用戶”}else{ usertype=“普通用戶”};\

print $1,usertype }’/etc/passwd

# 三元運算符替換if…else

awk –F : ‘{ usertype=$3<500?“系統用戶”: “普通用戶”;\

print $1,usertype }’/etc/passwd

l  $3<500:條件判斷

l  ?”系統用戶”:爲真,則“系統用戶”賦給usertype

l  :“普通用戶”:爲假,則“普通用戶”賦給usertype

# 三元運算符統計“系統用戶”和“普通用戶”數量

awk -F: '{$3<500?a++:b++}END{print a,b}' /etc/passwd

7.2、打印奇偶行

# 打印奇數行

awk ‘a=!a’flie

# 打印偶數行

awk ‘!(a=!a)’flie

解析:

我們知道awk的正則匹配是

image.png/

但如果我們不加print動作,僅僅有正則,那麼會默認打印$0

awk ‘/正則/’file

而在awk中,非0/非空str表示“真”。0/空表示“假”

# 注意,這不是正則,‘2’不爲0/空,打印file所有

awk '2' file

所以’a=!a’

1) a沒有定義,初始化a=‘’,a爲“假”

2) !a爲“真”

3) a=!a,a變爲“真”,打印第1行

4) !a又變爲“假”,不打印第2行

 

 

‘!(a=!a)’

1)a=!a爲真,!(a=!a)爲假,不打印 第1行

2)a=!a爲假,!(a=!a)爲真,打印第2行

8、參考文檔

awk從放棄到入門 (http://www.zsythink.net/?s=awk)

awk用法(使用入門) (https://www.cnblogs.com/emanlee/p/3327576.html)

官方文檔 (https://www.gnu.org/software/gawk/manual/html_node/index.html#SEC_Contents)

 

sed

sed命令是一個面向字符流的非交互式編輯器,按行來處理文本內容。在shell中,使用sed來批量修改文本內容是非常方便的。

 

1sed的工作原理

sed 把每一行都存在臨時緩存區中,對這個副本進行編輯,所以不會修改或破壞源文件。具體過程如下:

1)sed 把當前正在處理的行保存在一個臨時緩存區中,這個緩存區稱爲“模式空間”或“臨時緩衝”。

2)sed 對模式空間中的行後處理完畢後,就把該行發送到屏幕上(除非之前有命令刪除這一行或取消打印操作)。

3)sed處理完輸入文件的最後一行後, sed 便結束運行。

image.png

2sed命令詳解

2.1sed命令的語法格式

sed的命令格式

sed [option] 'sed command'filename

sed的腳本格式

sed [option] -f 'sed script'filename

2.2sed命令的選項(option)

-n :使用安靜(silent)模式。在一般 sed 的用法中,所有來自 STDIN 的數據一般都會被列出到終端上。但如果加上 -n 參數後,則只有經過sed 特殊處理的那一行(或者動作)纔會被列出來。

-e :多重編輯,且命令順序會影響結果

-f :直接將 sed 的動作寫在一個文件內, -f filename 則可以運行 filename 內的 sed 動作;

-r :sed 的動作支持的是延伸型正規表示法的語法。(默認是基礎正規表示法語法)

-i :直接修改讀取的文件內容,而不是輸出到終端。

2.3sed定位文本的方式

x

x爲行號

x,y

表示行號從x到y

/pattern

查詢包含模式的行

/pattern /pattern

查詢包含兩個模式的行

pattern/,x

在給定行號上查詢包含模式的行

x,/pattern/

通過行號和模式查詢匹配的行

x,y!

查詢不包含指定行號x和y的行

2.4sed操作命令(command

命 令

說 明

a\

在當前行後添加一行或多行。

sed ‘/pattern/a new_str’file;sed ‘1a new_str‘ file

c\

用新文本修改(替換)當前行中的文本

d

刪除行

i\

在當前行之前插入文本

h

把模式空間裏的內容複製到暫存緩存區

H

把模式空間裏的內容追加到暫存緩存區

g

取出暫存緩衝區裏的內容,將其複製到模式空間,覆蓋該處原有內容

G

取出暫存緩衝區裏的內容,將其複製到模式空間,追加在原有內容後面

l

列出非打印字符

p

打印匹配行(和-n選項一起合用)

=

顯示文件行號

{}

定位執行的命令組,“;”隔開

n

讀入下一輸入行,並從下一條命令而不是第一條命令開始處理

q

結束或退出 sed

r filename

從另一個文件中讀文本,類似輸入重定向   <

對所選行意外的所有行應用命令

s

用一個字符串替換另一個

2.5、替換標誌

g

在行內進行全局替換

p

打印行

w filename

寫文本到一個文件,類似輸出重定向   >

x

交換暫存緩衝區與模式空間的內容

y

傳送字符,替換單個字符(不能對正則表達式使用 y 命令)

2.6sed的正則表達式

元字符

功 能

示 例

示例的匹配對象

^

行首定位符

/^love/

匹配所有以 love 開頭的行

$

行尾定位符

/love$/

匹配所有以 love 結尾的行

.

匹配除換行外的單
  個字符

/l..e/

匹配包含字符 l、後跟兩個任意
  字符、再跟字母 e 的行

*

匹配零個或多個前
  導字符

/*love/

匹配在零個或多個空格緊跟着
  模式 love 的行

[]

匹配指定字符組內
  任一字符

/[Ll]ove/

匹配包含 love 和 Love 的行

[^]

匹配不在指定字符
  組內任一字符

/[^A-KM-Z]ove/

匹配包含 ove,但 ove 之前的那
  個字符不在 A 至 K 或 M 至 Z 間
  的行

\(..\)

保存已匹配的字符



&

保存查找串以便在
  替換串中引用

s/love/**&**/

符號&代表查找串。字符串 love
  將替換前後各加了兩個**的引
  用,即 love 變成**love**

\<

詞首定位符

/\<love/

匹配包含以 love 開頭的單詞的
  行

\>

詞尾定位符

/love\>/

匹配包含以 love 結尾的單詞的
  行

x\{m\}

連續 m 個 x

/o\{5\}/

分別匹配出現連續 5 個字母 o、
  至少 5 個連續的 o、或 5~10 個
  連續的 o 的行

x\{m,\}

至少 m 個 x

/o\{5,\}/


x\{m,n\}

至少 m 個 x,但不
  超過 n 個 x

/o\{5,10\}/


 

2.7、字符集

[:digit:]

所有數字,即[0-9]

[:lower:]

所有的小寫字母

[:upper:]

所有的大寫字母

[:alpha:]

所有的字母

[:alnum:]

相當於0-9a-zA-Z

[:space:]

空白字符

[:punct:]

所有標點符號

 

2.8sed實例

# {}的應用

sed -n '1,4{=;p}' passwd

# a\的應用

sed ‘/pattern/a new_str’file # 在匹配模式的下一行新,增str

sed ‘1a new_str‘ file # 在第1行後,新增str

# !的應用

# 過濾#註釋行和空格行

sed –n ‘/^#/!{/^$/!p}’file

l  /^#/!:打印除了#開頭的行

l  {/^$/!p}:打印除了空格行

# -e 的應用

# 刪除#註釋行和空行。有時-e的不同順序,會造成不同結果。比如 -e ’1a’–e ‘2a’

sed –e ‘/^#/d’-e ‘/^$/d’ file

# 將hello所在行的END替換爲tail

sed –i ‘/hello/s@END@tail@#’

l  @:地址定界符,還可以是/,#等其他特殊字符

# ()&

# 將目錄下的.txt文件批量命名爲.sh文件

find . –name ‘*.txt’ | sed –re ‘s#(.*).txt#mv & \1.sh#e’

l  (.*).txt:查找的文件,對應&

l  (.*):分組,對應\1,多個括號就依次對應\2,\3,…

l  e:執行mv命令

# \<\>

# 刪除文件中含有you這個單詞的行。\必須加

sed ‘/\<you\>/d’file

3、參考文檔

linux sed命令詳解(推薦) (http://www.jb51.net/article/111306.htm)

linux命令總結sed命令詳解 (https://www.cnblogs.com/ginvip/p/6376049.html)

sed命令詳解 (https://www.cnblogs.com/ctaixw/p/5860221.html)

 

grep

grep適合單純的查找或匹配文本。

1、grep的參數

--color=atuo或者—color:對匹配到的文本着色

-i:忽略大小寫

-n:顯示結果所在行號

-c:統計匹配到的行數。注意:是匹配到的總行數,不是匹配到的次數

-o:只顯示符合條件的字符串,但是不整行顯示。每個符合條件的字符串單獨顯示一行

-v:接啥排除啥

-w:匹配整個單詞,如果是字符創中包含這個單詞,則不會匹配

-Ax:輸出的時候包含結果所在行之後的指定行數,x是行數,A:after。如果有多個匹配結果。則每個結果的後x行都會顯示

-Bx:輸出的時候包含結果所在行之前的指定行數,x是行數,B:before。

-Cx:輸出的時候包含結果所在行之前和行之後的指定行數,x是行數,C:context

-e:實現多個選項的匹配,邏輯or關係

-q:靜默模式,不輸出任何信息。於“echo $?”合用,查看是否匹配到,0表示匹配到,1表示沒有匹配到

-P:使用兼容的perl的正則

-E:使用擴展正則表達式,同egrep

# -e的使用

grep –e’one’ –e’two’ file # 可以同時匹配one和two

練習題

 

1、將/etc/passwd 文件的前10行輸入到passwd中,將passwd變爲只有單詞/字母存在的文本

sed -nr 's#[:/0-9]+# #gp' passwd.txt  #對passwd.txt文件進行處理,將 FS 變爲空格

2、將/etc/passwd 文件的前10行輸入到passwd中,計算文件中每個單詞的重複數量

sed -nr 's#[:/0-9]+# #gp' passwd.txt | sed -nr 's# #\n#gp' | sort | uniq -c | sort –nr

l  sed -nr 's#[:/0-9]+# #gp' passwd.txt  #對passwd.txt文件進行處理,將 FS 變爲空格

awk 'BEGIN{RS="[:/0-9]+"}{print $0}' passwd.txt | head -n -1 | sort | uniq -c | sort -nr  # head -n -1 是因爲最後一行是空行,需要排除

3、從處理過的passwd文件中,找出第一列有12o的行,並打印行號

# awk使用{m,n},需要加--posix

awk --posix ‘$1~/o{1,2}/{print NR,$1}’passwd

4、統計某一文件裏空行的數量

sed -nr 's#^$##gp' file | wc -l

grep "^$" file |wc -l 

awk '/^$/{a=a+1} END{print a}' file

5、以 : 爲分隔符,統計/etc/passwd文件中$3>5的行數

awk -F: '{$3>5?a++:b++} END{print a}' /etc/passwd

awk -F: '$3>5{a++;print NR,$0} END{print a}' /etc/passwd

6、找出環境變量$PATH中,所有隻有三個任意字符的命令,如tee,並將它們重定向到command.txt中。每行顯示1一個,並統計總個數

find $(echo $PATH | tr ":" "\n") -type f -name "???" 1> command 2>/dev/null;wc -l command

7、處理以下文件內容,將域名取出,並根據域名進行技術排序處理(去重)

http://www.cbl.org/index.html

http://www.cbl.org/1.html

http://post.cbl.org/index.html

http://mp3.cbl.org/index.html

http://www.cbl.org/3.html

http://post.cbl.org/2.html

awk -F "/" '{a[$3]++} END{for(i in a){print i,a[i]}}' test

8處理以下文件內容,去重

111 222 333 444 222 222 111 111 11 11

22 33 44 55 33 33 55 22

77 88 77 77 88 99 33 33

awk '{for(i=1;i<=NF;i++)a[$i,NR]++} \

{for (j in a) {split(j,m,SUBSEP);if(m[2]==NR)printf m[1]" "} printf "\n"}' test

l  a[$i,NR]:二維數組

l  for (j in a):遍歷,j是二維數組

l  split(j,m,SUBSEP):切割二維數組,SUBSEP是切割二維數組的分隔符

l  printf m[1]:如果使用print,則每個m[1],都會自動換行。printf不會,print需要自定義格式

l  printf "\n":換行。awk是一行一行處理的,一行處理完,換行,美化輸出


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章