28分鍾學會Linux三劍客


把簡單的技術學到極致就是高手。

前言

Linux三劍客指的是grep、sed以及awk命令的使用,這三個命令功能異常強大,大到沒朋友。grep命令主打“查找”,sed命令主打“編輯”,awk命令主打“分割處理”。之所以是28分鍾,大概是我比較嚴謹吧,數字也比較吉利。

下面給和網管相關的幾個例子看看實用的效果,改進建議也經常會用這些命令寫自動化腳本。如果以下例子秒懂,那不用看了,該干嘛干嘛。

1、掃描本地ip地址

ifconfig eth0 | grep "inet addr:" | awk '{print $2}' | sed 's/addr://g'

2、掃描端口號被哪個進程占用

netstat -anp | awk '{print $4,$7}' | grep 31006 | sed -n '1p' | awk '{print $2}' | awk -F'/' '{print $1}' | xargs ps -lfp | sed -n '2p' | awk '{print $17}'

3、獲取某個進程的堆棧

ps -elf | grep -v grep | grep necomm_agent | awk '{print $4}' | xargs gstack > yp.txt

4、批量重命名網元license備份的文件名

for i in `ls`; do mv -f $i `echo $i | sed 's/^[a-zA-Z0-9].*_[a-zA-Z0-9].*_\([0-9]\{8\}\)\(_\)\([0-9]\{6\}\)\(\.txt\)$/Lic_Esn_\1\2\3/'`; done

5、統計某個文件夾下的文件占用的字節數

ls -l | awk 'BEGIN {size=0;} {size = size + $5;} END{print “[end]size is ”, size/1024,1024, “M”}'

里面有幾個知識點先行贅述。

1、  何時需要xargs?

1)  有些命令本身是不支持管道,這個時候要加xargs,本身支持管道的命令有限如

cut grep sort uniq wc tee join split等

如下面的例子

echo "/opt" | ls -l        //ls本身是不支持管道,所以對於前面管道輸出的內容會忽略,不會輸出/opt目錄下內容

echo "/opt" | xargs ls -l   //加上xargs,執行的結果就是輸出/opt下目錄的內容

2)  命令雖然支持管道,但如果不加xargs和加xargs意義也截然不同。

比如網管中經常用到到在某個目錄下查找某個abc字符串:

find ./ | grep “abc”   //這個命令不會在目錄下文件查找,而是把find出來的內容中查找,相當於在一群文件名中查找是否有包含abc的文件名。

find ./ | xargs grep "abc" //這個命令是把find出來的東西當做參數傳遞給管道后的內容,相當於在find出來的文件內容中查找是否包含字符串abc。

2、  正則表達式

一個正則表達式通常被稱為一個模式,用來描述或匹配一系列符合某個語法規則的字符串。正則表達式有多重不同的風格,但大同小異,下面列出PCRE中常用的元字符和意義。POSIX正則表達式分為基本正則表達式(BRE)和擴展表達式(ERE)。

目前很多UNIX工具程序沿用某一種正則表達式形式來強化本身的功能。常用的包括

1)  grep工具組:grep和egrep

2)  改變輸入流的sed流編輯器

3)  字符串處理程序語言:awk

4)  文件查詢程序:more、less

5)  文本編輯器:vi

 

字符

意義

支持的類型

\

將下一個字符標記為特殊字符,或者將一個元字符轉義為普通字符。如n加上\匹配一個換行符。\\則匹配一個\字符。

BOTH

^

匹配輸入字符串的開始位置

BOTH

$

匹配輸入字符串的結束位置

BOTH

*

匹配前面的子表達式0次或者多次,如zo*能匹配z和zoo

BOTH

匹配前面的子表達式0次或者1次

ERE

.

匹配除\n之外的任何單個字符

BOTH

+

匹配前面的子表達式1次或者多次,如zo+能匹配zo和zoo,但不能匹配z

ERE

|

匹配於|符號前或后的正則表達式

ERE

{n,m}

最少匹配n次,最多匹配m次和BRE的區別是不需要加\

ERE

\{n\}

匹配前面的子表達式n次

BRE

\{n,\}

至少匹配前面的子表達式n次

BRE

\{n,m\}

最少匹配n次,最多匹配m次

BRE

\(\)

將\(與\)間的模式存儲在特殊的保留空間

BRE

\digit

重復在\(與\)方括號內第n個子模式至此點的模式

BRE

[xyz]

匹配xyz中的任何一個字符

BOTH

[^xyz]

匹配未包含的任意字符

BOTH

[x-z]

匹配小寫的字符

BOTH

如:

grep 'a\{3\}' test.txt  \\查找test.txt中包含3個a的行

grep '^aa' test.txt    \\查找test.txt中以aa開頭的行

grep ‘^$’ test.txt     \\查找所有空行

后向引用

后向引用指的是“匹配於正則表達式匹配的先前的部分”。后向引用只在BRE中存在。使用后向引用的步驟有兩步。

1、  將子表達式包圍在\(與\)里,單個模式里可包含最多9個子表達式

2、  在模式之后使用\digit,digit是介於1至9的數字,指的是“匹配於第n個先前方括號內子表達式匹配成功的字符”

grep ‘\(why\).*\1’ test.txt           \\一行里可以匹配why..why

grep ‘\(ab\)\(cd\)[def]*\2\1’ test.txt   \\匹配abcddcdab

\< \>

匹配單詞的開頭與結尾。單詞是由字母、數字及下划線組成。

以下圖為各種UNIX程序與其使用的正則表達式

類型

Grep

sed

vi

more

egrep

awk

BRE

 

 

ERE

 

 

 

 

\< \>

 

 

 

好,進入正題。

一、 grep命令

grep是一種強大的文本搜索工具,它能使用正則表達式搜索文本,並把匹配的行打印出來,其格式如下:

grep [選項] pattern file

常用的選項

-v 過濾指定字符串內容的行

-i  不區分大小寫

-n  順便打印出行號

-c  計算出符合行的次數

-E 默認grep只支持基本的正則表達式,加上-E支持擴展的正則表達式,grep –E和egrep意義一樣,擴展的正則表達式有’+’,’?’,’|’,’()’

常用的命令

ps –elf | grep –v grep | grep “necomm_agent” //如果不加grep –v grep,輸出2條內容

grep –i ‘abc’ test.txt//忽略大小寫,找出test.txt包含abc的行

grep –v ‘^$’ test.txt > testnew.txt //過濾test.txt的空行

二、 sed命令

sed是操作、過濾和轉換文本內容的強大工具,常用功能增刪改查,過濾,取行。

格式如下:

sed [options] [sed-commands] [input-file]

sed [選項] [sed命令] [輸入文件]

說明:

options常用的有:

-n :抑制默認輸出

-e 執行多條編輯命令

-i:直接在原文件中修改

sed-commands既可以是單個sed命令,也可以是多個sed命令組合

input-file(輸入文件)是可選項,sed還能夠從標准輸入如管道獲取輸入

工作原理

sed是從文件或管道中讀取一行,放在模式空間中,進行處理,處理完輸出一行;再讀取一行,再處理一行

模式空間:sed內部的一個臨時緩存,用於存放讀取到的內容

1

a 追加文本到指定行后

i 插入文本到指定行前

i 單行增加

sed '2a abc' test.txt

sed '2i abc' test.txt

ii 增加多行

sed '2a abc\

cde' test.txt

指定執行的地址范圍

sed可以對單行或多行進行處理,如果在sed命令前面不指定地址范圍,那么默認會匹配所有行。

用法 n1[,n2] {sed-commands}

地址用逗號分隔的,n1,n2可以是數字、正則表達式、或兩者的組合表示。$表示最后一行。

/abc/,/fff/{sed-commands} //對匹配abc的行到匹配fff的行操作

2)刪

d 刪除指定的行

sed '/aaa/d' test.txt

3)

i c用新行取代舊行

sed '2c abc' test.txt

ii  文本替換

sed 's/abc/bcd/g' test.txt //后面的g代表全局替換,如果不加g,只替換每行第一個匹配的字符串

sed ‘s/^/abc /’ test.txt //在test.txt每行前插入abc

sed -i '/aaa/s/abc/bcd/g' test.txt //加上-i代表修改了文件test.txt

替換部分有幾個特殊的元字符,它們分別是

&:被pattern匹配的內容

\num:被pattern匹配的第num個分組(正則表達式的概念,\(…\)括起來的部分成為分組)

sed '/d/s/ab/&jj/' test.txt //將匹配d內容的行中的ab替換為abjj

echo this is digit 7 in a number | sed 's/digit \([0-9]\)/\1/' //將命令中的digit 7 修改為7

4)

p 輸出指定內容,但默認會輸出2次匹配的結果,因此使用n取消默認輸出

按行查詢

sed -n '2p' test.txt

按字符串查詢

sed –n ‘/abc/p’ test.txt

混合查詢

sed –n ‘2,/abc/p’ test.txt

5多命令編輯

sed -e '1,5d' -e 's/test/check/' test.txt

 

三、awk命令

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

使用方法

awk [-F field-separator] '{pattern + action}' {filename}

pattern表示awk在數據庫中查找的內容,action表示找到匹配內容所執行的一系列命令,pattern就是要表示的正則表達式,用斜杠括起來。

-F 域分隔符 是可選的,如果不指定,默認的域分隔符是空格

awk '{print $1}'

 

cat /etc/passwd |awk  -F ':'  'BEGIN {print "name,shell"}  {print $1","$7} END {print "blue,/bin/nosh"}'

 

執行流程為:先執行BEGIN,然后讀取文件,讀入有\n換行符分割的一條記錄,然后將記錄按指定的域分隔符划分域,填充域,$0表示所有域,$1表示第一個域,$n表示第n個域,隨后開始執行模式所對應的動作action。

然后開始讀入第二條記錄.....直到所有的記錄都讀完,最后執行END操作

常用的命令

 

awk -F: '/^root/' /etc/passwd 如果沒有指定action,默認輸出每行的內容

awk -F: '/^ftp/{print $4}' /etc/passwd 指定了action

ls -l|awk '/^[^d]/ {print $9"\t"$5} {tot+=$5} END{print "totKB:" tot}'

 

統計某個文件夾下的文件占用的字節數

ls -l | awk 'BEGIN {size=0;} {size = size + $5;} END{print “[end]size is ”, size/1024,1024, “M”}'

 

awk的編程是從C語言借鑒過來的,所以語法類似

如test.txt中包含姓名和各科成績,輸出姓名和最大成績

 

 awk 'BEGIN {MAX=0;} {NAME = $1; for(x=2; x<=NF; x++) { if($x >= MAX) { MAX=$x}} printf "name:%s  MAX:%d\n", NAME,MAX; MAX=0}' test.txt

 


免責聲明!

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



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