日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

在Linux里awk与sed的区别,linux awk和sed讲解

發(fā)布時間:2024/7/19 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Linux里awk与sed的区别,linux awk和sed讲解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

sed 工具簡介

在了解了一些正規(guī)表示法的基礎應用之后,再來呢?呵呵~兩個東西可以玩一玩的,那就是 sed 跟 awk 了!

這兩個家伙可是相當?shù)挠杏玫陌?#xff01;舉例來說,鳥哥寫的 logfile.sh 分析登錄文件的小程序,

絕大部分分析關鍵詞的取用、統(tǒng)計等等,就是用這兩個寶貝蛋來幫我完成的! 那么你說,要不要玩一玩啊?!

^_^

我們先來談一談 sed 好了,基本上, sed 可以分析 Standard Input (STDIN) 的數(shù)據(jù),

然后將數(shù)據(jù)經(jīng)過處理后,再將他輸出到 standrad out (STDOUT) 的一個工具。

至于處理呢?可以進行取代、刪除、新增、擷取特定行等等的功能呢!很不錯吧~ 我們先來了解一下 sed

的用法,再來聊他的用途好了!

[root@linux ~]# sed [-nefri] [動作]

參數(shù):

-n?:使用安靜(silent)模式。在一般 sed

的用法中,所有來自 STDIN

的數(shù)據(jù)一般都會被列出到屏幕上。但如果加上 -n

參數(shù)后,則只有經(jīng)過

sed 特殊處理的那一行(或者動作)才會被列出來。

-e?:直接在指令列模式上進行 sed

的動作編輯;

-f?:直接將 sed 的動作寫在一個檔案內(nèi), -f

filename 則可以執(zhí)行 filename 內(nèi)的

sed 動作;

-r?:sed

的動作支持的是延伸型正規(guī)表示法的語法。(預設是基礎正規(guī)表示法語法)

-i?:直接修改讀取的檔案內(nèi)容,而不是由屏幕輸出。

動作說明:?[n1[,n2]]function

n1, n2 :不見得會存在,一般代表『選擇進行動作的行數(shù)』,舉例來說,如果我的動作

是需要在 10 到 20

行之間進行的,則『 10,20[動作行為] 』

function 有底下這些咚咚:

a?:新增, a

的后面可以接字符串,而這些字符串會在新的一行出現(xiàn)(目前的下一行)~

c?:取代, c 的后面可以接字符串,這些字符串可以取代

n1,n2 之間的行!

d?:刪除,因為是刪除啊,所以 d

后面通常不接任何咚咚;

i?:插入, i

的后面可以接字符串,而這些字符串會在新的一行出現(xiàn)(目前的上一行);

p?:打印,亦即將某個選擇的數(shù)據(jù)印出。通常 p 會與參數(shù)

sed -n 一起運作~

s?:取代,可以直接進行取代的工作哩!通常這個 s

的動作可以搭配

正規(guī)表示法!例如 1,20s/old/new/g 就是啦!

范例:

范例一:將 /etc/passwd 的內(nèi)容列出,并且我需要打印行號,同時,請將第 2~5 行刪除!

[root@linux ~]# nl /etc/passwd |sed '2,5d'

1?root:x:0:0:root:/root:/bin/bash

6?sync:x:5:0:sync:/sbin:/bin/sync

7?shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

.....(后面省略).....

# 看到了吧?因為 2-5 行給他刪除了,所以顯示的數(shù)據(jù)中,就沒有 2-5 行啰~

# 另外,注意一下,原本應該是要下達 sed -e 才對,沒有 -e 也行啦!

# 同時也要注意的是, sed 后面接的動作,請務必以 '' 兩個單引號括住喔!

# 而,如果只要刪除第 2 行,可以使用 nl /etc/passwd | sed '2d'

來達成,

# 至于第 3 到最后一行,則是 nl /etc/passwd | sed '3,$d'

的啦!

范例二:承上題,在第二行后(亦即是加在第三行)加上『drink tea?』字樣!

[root@linux ~]# nl /etc/passwd |sed '2a drink tea'

1?root:x:0:0:root:/root:/bin/bash

2?bin:x:1:1:bin:/bin:/sbin/nologin

drink tea

3?daemon:x:2:2:daemon:/sbin:/sbin/nologin

# 嘿嘿!在 a 后面加上的字符串就已將出現(xiàn)在第二行后面啰!那如果是要在第二行前呢?

# nl /etc/passwd | sed '2i drink tea' 就對啦!

范例三:在第二行后面加入兩行字,例如『Drink tea or .....』『drink

beer?』

[root@linux ~]# nl /etc/passwd | sed '2a Drink tea or ......\

> drink beer ?'1?root:x:0:0:root:/root:/bin/bash

2?bin:x:1:1:bin:/bin:/sbin/nologin

Drink tea or ......

drink beer ?

3?daemon:x:2:2:daemon:/sbin:/sbin/nologin

# 這個范例的重點是,我們可以新增不只一行喔!可以新增好幾行~

# 但是每一行之間都必須要以反斜線 \ 來進行新行的增加喔!所以,上面的例子中,

# 我們可以發(fā)現(xiàn)在第一行的最后面就有 \ 存在啦!那是一定要的喔!

范例四:我想將第2-5行的內(nèi)容取代成為『No 2-5 number』呢?

[root@linux ~]# nl /etc/passwd | sed '2,5c No 2-5

number'

1?root:x:0:0:root:/root:/bin/bash

No 2-5 number

6?sync:x:5:0:sync:/sbin:/bin/sync

# 沒有了 2-5 行,嘿嘿嘿嘿!我們要的數(shù)據(jù)就出現(xiàn)啦!

范例五:僅列出第 5-7 行

[root@linux ~]# nl /etc/passwd | sed -n '5,7p'

5?lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin

6?sync:x:5:0:sync:/sbin:/bin/sync

7?shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown

# 為什么要加 -n 的參數(shù)呢?您可以自行下達 sed '5,7p'

就知道了!(5-7行會重復輸出)

# 有沒有加上 -n 的參數(shù)時,輸出的數(shù)據(jù)可是差很多的喔!

范例六:我們可以使用 ifconfig 來列出 IP ,若僅要 eth0 的 IP 時?

[root@linux ~]# ifconfig eth0

eth0?Link

encap:Ethernet?HWaddr

00:51:FD:52:9A:CA

inet

addr:192.168.1.12?Bcast:192.168.1.255?Mask:255.255.255.0

inet6 addr:

fe80::250:fcff:fe22:9acb/64 Scope:Link

UP

BROADCAST RUNNING

MULTICAST?MTU:1500?Metric:1

.....(以下省略).....

# 其實,我們要的只是那個 inet addr:..那一行而已,所以啰,利用 grep 與 sed 來捉

[root@linux ~]# ifconfig eth0 | grep 'inet ' | sed 's/^.*addr://g'

| \

> sed 's/Bcast.*$//g'#

您可以將每個管線 (|) 的過程都分開來執(zhí)行,就會曉得原因啰!

# 去頭去尾之后,就會得到我們所需要的 IP 亦即是 192.168.1.12 啰~

范例七:將 /etc/man.config 檔案的內(nèi)容中,有 MAN

的設定就取出來,但不要說明內(nèi)容。

[root@linux ~]# cat /etc/man.config | grep 'MAN'| sed 's/#.*$//g' |

\

> sed '/^$/d'#

每一行當中,若有 # 表示該行為批注,但是要注意的是,有時候,

# 批注并不是寫在第一個字符,亦即是寫在某個指令后方,如底下的模樣:

# 『shutdown -h now # 這個是關機的指令』,批注 # 就在指令的后方了。

# 因此,我們才會使用到將 #.*$ 這個正規(guī)表示法!

范例八:利用 sed 直接在 ~/.bashrc 最后一行加入『# This is a test』

[root@linux

~]# sed -i '$a # This is a

test'?~/.bashrc#

上頭的 -i 參數(shù)可以讓你的 sed 直接去修改后面接的檔案內(nèi)容喔!而不是由屏幕輸出。

# 至于那個

$a?則代表最后一行才新增的意思。

總之,這個 sed 不錯用啦!而且很多的 shell script 都會使用到這個指令的功能~ sed

可以幫助系統(tǒng)管理員管理好日常的工作喔!要仔細的學習呢!

awk 工具簡介

相較于 sed 常常作用于一整個行的處理, awk 則比較傾向于一行當中分成數(shù)個『字段』來處理。 因此,awk

相當?shù)倪m合處理小型的數(shù)據(jù)數(shù)據(jù)處理呢!awk 通常運作的模式是這樣的:

[root@linux ~]# awk '條件類型1{動作1} 條件類型2{動作2} ...' filename awk

可以處理后續(xù)接的檔案,也可以讀取來自前個指令的 standard output 。 但如前面說的, awk

主要是處理『每一行的字段內(nèi)的數(shù)據(jù)』,而預設的『字段的分隔符為 "空格鍵" 或 "[tab]鍵" 』!舉例來說,我們用 last

可以將登入者的數(shù)據(jù)取出來, 結果如下所示:

[root@linux ~]#lastdmtsai?pts/0?192.168.1.12?Mon Aug 22

09:40?still logged

in

root?tty1?Mon Aug 15

11:38 -

11:39?(00:01)

reboot?system

boot?2.6.11?Sun Aug 14

18:18?(7+15:41)

dmtsai?pts/0?192.168.1.12?Fri Aug 12

12:07 -

12:08?(00:01)

若我想要取出賬號與登入者的 IP ,且賬號與 IP 之間以 [tab] 隔開,則會變成這樣:

[root@linux ~]# last | awk '{print $1 "\t" $3}'

dmtsai?192.168.1.12

root?Mon

reboot?boot

dmtsai?192.168.1.12

因為不論哪一行我都要處理,因此,就不需要有 "條件類型" 的限制!我所想要的是第一欄以及第三欄,

但是,第二行及第三行的內(nèi)容怪怪的~這是因為數(shù)據(jù)格式的問題啊!所以啰~使用 awk

的時候,請先確認一下您的數(shù)據(jù)當中,如果是連續(xù)性的數(shù)據(jù),請不要有空格或 [tab]

在內(nèi),否則,就會像這個例子這樣,會發(fā)生誤判喔!

另外,由上面這個例子您也會知道,在每一行的每個字段都是有變量名稱的,那就是 $1, $2... 等變量名稱,以上面的例子來說,

dmtsai 是 $1 ,因為他是第一欄嘛!至于 192.168.1.12 是第三欄, 所以他就是 $3

啦!后面以此類推~呵呵!還有個變數(shù)喔!那就是 $0 ,$0 代表『一整列資料』的意思~ 以上面的例子來說,第一行的 $0

代表的就是『dmtsai pts/0.... 』那一行啊! 由此可知,剛剛上面四行當中,整個 awk

的處理流程是:

讀入第一行,并將第一行的資料填入 $0, $1, $2.... 等變數(shù)當中;

依據(jù) "條件類型" 的限制,判斷是否需要進行后面的 "動作";

做完所有的動作與條件類型;

若還有后續(xù)的『行』的數(shù)據(jù),則重復上面 1~3 的步驟,直到所有的數(shù)據(jù)都讀完為止。經(jīng)過這樣的步驟,您會曉得, awk

是『以行為一次處理的單位』, 而『以字段為最小的處理單位』。好了,那么 awk 怎么知道我到底這個數(shù)據(jù)有幾行?有幾欄呢?這就需要

awk 的內(nèi)建變量的幫忙啦~

變量名稱

代表意義

NF

每一行 ($0) 擁有的字段總數(shù)

NR

目前 awk 所處理的是『第幾行』數(shù)據(jù)

FS

目前的分隔字符,預設是空格鍵

我們繼續(xù)以上面例子來做說明,如果我想要列出每一行的賬號,并且列出目前處理的行數(shù), 并且說明,該行有多少字段,則可以這樣

(注意, awk 后續(xù)的所有動作以 ' 括住, 所以,內(nèi)容如果想要以 print

打印時,記得,非變量的文字部分,包含上一小節(jié)

printf

提到的格式中,都需要使用雙引號來定義出來喔!)

[root@linux ~]# last | awk '{print $1 "\t lines: " NR "\t columes:

" NF}'

dmtsai?lines:

1?columes:

10

root?lines:

2?columes:

9

reboot?lines:

3?columes:

9

dmtsai?lines:

4?columes:

10

這樣可以了解 NR 與 NF 的差別了吧?好了,底下來談一談所謂的 "條件類型" 了吧!

awk 的邏輯運算字符

既然有需要用到 "條件" 的類別,自然就需要一些邏輯運算啰~例如底下這些:

運算單元

代表意義

>?大于

小于

>=?大于或等于

小于或等于

==?等于

!=?不等于

值得注意的是那個 == 的符號,因為在『邏輯運算』上面, 就是所謂的大于、小于、等于等等的判斷式上面,我們習慣上是以 ==

來表示,而如果是直接給予一個值,例如變量設定時,就直接使用 = 而已。 好了,我們實際來運用一下邏輯判斷吧!舉例來說,在

/etc/passwd 當中是以冒號 ":" 來作為字段的分隔,那假設我要查閱,第三欄小于 10 以下的數(shù)據(jù),并且僅列出賬號與第三欄,

那么可以這樣做:

[root@linux ~]# cat /etc/passwd | \

> awk '{FS=":"} $3?root:x:0:0:root:/root:/bin/bash

bin?1

daemon?2

......(以下省略)......

有趣吧!不過,怎么第一行沒有正確的顯示出來呢?這是因為我們讀入第一行的時候, 那些變數(shù) $1, $2...

預設還是以空格鍵為分隔的,所以雖然我們定義了 FS=":" 了, 但是卻僅能在第二行后才開始生效。那么怎么辦呢?我們可以預先設定

awk 的變量啊! 利用 BEGIN 這個關鍵詞喔!這樣做:

[root@linux ~]# cat /etc/passwd | \

> awk 'BEGIN {FS=":"} $3?......(以下省略)......

很有趣吧!而除了 BEGIN 之外,我們還有 END 呢!另外,如果要用 awk 來進行『計算功能』呢?以底下的例子來看,

假設我有一個薪資數(shù)據(jù)表,內(nèi)容是這樣的:

Name?1st?2nd?3th

VBird?23000?24000?25000

DMTsai?21000?20000?23000

Bird2?43000?42000?41000

如何幫我計算每個人的總額呢?而且我還想要格式化輸出喔! 你可以將上面的數(shù)據(jù)儲存成一個名稱為 pay.txt 的檔案,則:

[root@linux ~]# cat pay.txt | \

> awk 'NR==1{printf "s s s s s\n",$1,$2,$3,$4,"Total" }

NR>=2{total = $2 + $3 + $4

printf "s d d d .2f\n", $1, $2, $3, $4,

total}'?Name?1st?2nd?3th?Total

VBird?23000?24000?25000?72000.00

DMTsai?21000?20000?23000?64000.00

Bird2?43000?42000?41000?126000.00

上面的例子有幾個重要事項應該要先說明的:

所有的動作,亦即在 {} 內(nèi)的動作,如果有需要多個指令輔助時,可利用分號『;』間隔, 或者直接以 [Enter]

按鍵來隔開每個指令,例如上面的 NR>=2 后面接的動作, 利用 total = ... 那個指令來指定加總,而后續(xù)則以

printf 來格式化輸出!

邏輯運算當中,如果是『等于』的情況,則務必使用兩個等號『==』!

格式化輸出時,在 printf 的格式設定當中,務必加上 \n

,才能進行分行!

與 bash shell 的變量不同,在 awk 當中,變量可以直接使用,不需加上 $ 符號。

利用 awk 這個玩意兒,就可以幫我們處理很多日常工作了呢!真是好用的很~ 此外, awk

的輸出格式當中,常常會以?printf

來輔助,所以, 最好您對 printf 也稍微熟悉一下比較好啦!另外, awk 的動作內(nèi) {} 也是支持 if (條件) 的喔!

舉例來說,上面的指令可以修訂成為這樣的

[root@linux ~]# cat pay.txt | \

> awk '{if(NR==1) printf "s s s s

s\n",$1,$2,$3,$4,"Total"}

NR>=2{total = $2 + $3 + $4

printf "s d d d .2f\n", $1, $2, $3, $4, total}'

你可以仔細的比對一下上面兩個輸入有啥不同~從中去了解兩種語法吧! 我個人是比較傾向于使用第一種語法,因為會比較有統(tǒng)一性啊!

^_^

總結

以上是生活随笔為你收集整理的在Linux里awk与sed的区别,linux awk和sed讲解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。