awk sed 總結

Awk總結筆記mysql

 

 

 

 

介紹

 

90年代 new awk :nawkios

Linux 的是gawk 咱們簡化awknginx

 

 

用法

 

#  awk [options ] ‘scripts’ file1 file2 ....web

# awk [options ] ‘PATTERN {action }’ file1 file2 ....正則表達式

 

讀入文本先切片以下 切5片sql

每片$n  整行$0shell

 

 

每行片數不同centos

Print

 

內置變量數組

    如下爲awk內置變量:緩存

          ARGC        命令行參數個數

          FILENAME    當前輸入文檔的名稱

          FNR        當前輸入文檔的當前記錄編號,尤爲當有多個輸入文檔時有用

          NR        輸入流的當前記錄編號

          NF        當前記錄的字段個數

          FS        字段分隔符

          OFS        輸出字段分隔符,默認爲空格

          ORS        輸出記錄分隔符,默認爲換行符\n

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

    示例:

 

顯示第一列字段  第一片

[root@centos5 awk]# cat a.txt 

welcome to my heart

i am liujianzuo 

how are u?

 

[root@centos5 awk]# awk '{print $1}' a.txt 

welcome

i

How

 

[root@centos5 awk]# df -hP  #顯示到一行

Filesystem            Size  Used Avail Use% Mounted on

/dev/sda3             7.1G  3.2G  3.6G  48% /

/dev/sda1             198M   13M  176M   7% /boot

tmpfs                  63M     0   63M   0% /dev/shm

/dev/sdb1              99M  6.1M   88M   7% /data

[root@centos5 awk]# df -h|awk '{print $1}'       

Filesystem

/dev/sda3

/dev/sda1

tmpfs

/dev/sdb1

 

-F 指定分隔符

相似cut -d

[root@centos5 awk]# awk -F : '{print $1}' /etc/passwd 

root

bin

daemon

adm

lp

sync

shutdown

halt

mail

news

uucp

operator

games

gopher

ftp

nobody

nscd

vcsa

pcap

ntp

dbus

若是你的列數不一致 怎麼取左後一列 $NF

 

 

[root@centos5 awk]# awk -F : '{print $NF}' /etc/passwd 

/bin/bash

/sbin/nologin

/sbin/nologin

/sbin/nologin

/sbin/nologin

/bin/sync

/sbin/shutdown

/sbin/halt

/sbin/nologin

 

/sbin/nologin

/sbin/nologin

/sbin/nologin

 

打印倒數第2字段 將NF作數學運算

[root@centos5 awk]# cat a.txt 

welcome to my heart

i am liujianzuo 

how are u?

[root@centos5 awk]# awk '{print $(NF-2)}' a.txt  

to

i

how

 

-F 改變分隔符 FS字段分隔符讀入的時候也能實現

[root@centos5 awk]# awk -v FS=: '{print $NF}' /etc/passwd|tail -3   

/sbin/nologin

/bin/bash

/bin/bash

 

輸出的分隔符 OFS 默認是逗號分開變量,輸出空格的

[root@centos5 awk]# awk '{print $1 $2}' a.txt                       

welcometo

iam

howare

[root@centos5 awk]# awk '{print $1,$2}' a.txt  

welcome to

i am

how are

[root@centos5 awk]# awk -v OFS=: '{print $1,$2}' a.txt   

welcome:to

i:am

how:are

Printf

 

字符串個數%s 雙引號引發來

不會自動換行 須要\n

格式符候還能夠加修飾符

以下是每一行開始第一列字段是10個字符對其,第二列字段是1個字符對其,默認右對齊

,不會自動換行

[root@centos5 awk]# awk '{printf "%10s,%s",$1,$2}' a.txt  

   welcome,to         i,am       how,are[root@centos5 awk]# 

讓其換行\n

[root@centos5 awk]# awk '{printf "%10s,%s\n",$1,$2}' a.txt 

   welcome,to

         i,am

       how,are

輸出左對齊 修飾符 -

[root@centos5 awk]# awk '{printf "%-10s,%-s\n",$1,$2}' a.txt 

welcome   ,to

i         ,am

how       ,are

 

格式之間的符號會輸出,不須要寫

[root@centos5 awk]# awk '{printf "%-10s%-s\n",$1,$2}' a.txt  

welcome   to

i         am

how       are

 

print輸出重定向

 

 

 

 

將print 打印結果輸出

[root@centos5 awk]# awk -F : '{printf "%-10s %i\n",$1,$3 > "/dev/stderr" }' /etc/passwd   #改變輸出流,引號引發來

[root@centos5 awk]# awk -F : '{printf "%-10s %i\n",$1,$3 > "/server/scripts/awk/passwd.log" }' /etc/passwd     #改變輸出流          

[root@centos5 awk]# cat passwd.log  

root       0

bin        1

daemon     2

adm        3

lp         4

sync       5

shutdown   6

halt       7

mail       8

news       9

uucp       10

operator   11

games      12

gopher     13

ftp        14

nobody     99

nscd       28

vcsa       69

pcap       77

ntp        38

dbus       81

avahi      70

rpc        32

mailnull   47

smmsp      51

oprofile   16

sshd       74

rpcuser    29

nfsnobody  65534

xfs        43

haldaemon  68

avahi-autoipd 100

oldboy     500

mysql      501

nginx      502

nagios     503

disdata    999

ayibang    1000

 

Awk的操做符

 

 

正則匹配=應該用[=]

 

 

 

 

這裏y是種模式

 

 

第三個字符串操做符實例

[root@centos5 awk]# awk 'BEGIN{print "a" "b"}'        

ab

第五個模式匹配

匹配某一行第一個字段是以root開頭的模式咱們就打印第3 4 最後一個字段

[root@centos5 awk]# awk -F : '$1 ~ /^root/ {print $3,$4,$NF}' /etc/passwd

0 0 /bin/bash

 

Awk的模式

 

 

 

 

 

 

正則表達式 模式+動做

awk正則表達式使用外部變量

 

awk的正則表達式匹配中,若是要使用外部shell
變量,先在變量外加雙引號,再加單引號便可,如:

for i in read write print; 

do 

cat file.txt | awk '{ if ($7~/'"$i"'/) {print $0} }'| wc -l ; 

done

 

匹配pation以後是動做以下例子,匹配bash這個模式後動做是打印匹配的包含的所有

# awk [options ] 'PATTERN {action }' file1 file2 ....

 

[root@centos5 awk]# awk -F : '/bash/ {print $0}' /etc/passwd        root:x:0:0:root:/root:/bin/bash

oldboy:x:500:500::/home/oldboy:/bin/bash

disdata:x:999:999::/home/disdata:/bin/bash

ayibang:x:1000:1000::/home/ayibang:/bin/bash

[root@centos5 awk]# awk -F : '/bash/ {print $1}' /etc/passwd 

root

oldboy

disdata

ayibang

表達式

 

 

[root@centos5 awk]# awk -F : '$3 >= 500 {print $1}' /etc/passwd     

nfsnobody

oldboy

mysql

nginx

nagios

disdata

ayibang

[root@centos5 awk]# awk -F : '$3 >= 500 {print $1,$3}' /etc/passwd

nfsnobody 65534

oldboy 500

mysql 501

nginx 502

nagios 503

disdata 999

ayibang 1000

 

匹配指定範圍 的模式

/bash/,/500/

[root@centos5 ceshi]# awk '/bash|500/ {print $0}' /etc/passwd

root:x:0:0:root:/root:/bin/bash

oldboy:x:500:500::/home/oldboy:/bin/bash

disdata:x:999:999::/home/disdata:/bin/bash

ayibang:x:1000:1000::/home/ayibang:/bin/bash

liujianzuo:x:1001:1001::/home/liujianzuo:/bin/bash

Begin end 特殊模式

[root@centos5 ~]# awk -F: '$3>=500 {print "USERNAME       UID";printf "%-15s%s\n",$1,$3}' /etc/passwd    #在awk預讀每一行的時候,都打印一行

USERNAME       UID

nfsnobody      65534

USERNAME       UID

oldboy         500

USERNAME       UID

mysql          501

USERNAME       UID

nginx          502

USERNAME       UID

nagios         503

USERNAME       UID

disdata        999

USERNAME       UID

ayibang        1000

[root@centos5 ceshi]# awk -F: 'BEGIN{print "USERNAME       UID"} $3 >= 500 {printf "%-15s%s\n",$1,$3}' /etc/passwd 

USERNAME       UID

nfsnobody      65534

oldboy         500

mysql          501

nginx          502

nagios         503

disdata        999

ayibang        1000

liujianzuo     1001

 

[root@centos5 ceshi]# awk -F: 'BEGIN{print "USERNAME       UID"} {if($3 >= 500) printf "%-15s%s\n",$1,$3}' /etc/passwd

USERNAME       UID

nfsnobody      65534

oldboy         500

mysql          501

nginx          502

nagios         503

disdata        999

ayibang        1000

liujianzuo     1001

 

[root@centos5 ceshi]# awk -F: 'BEGIN{print "USERNAME       UID"}{printf "%-15s%s\n",$1,$3}' /etc/passwd 

USERNAME       UID

root           0

bin            1

daemon         2

adm            3

lp             4

sync           5

shutdown       6

halt           7

mail           8

news           9

uucp           10

operator       11

games          12

gopher         13

ftp            14

nobody         99

nscd           28

vcsa           69

pcap           77

ntp            38

dbus           81

avahi          70

rpc            32

mailnull       47

smmsp          51

oprofile       16

sshd           74

rpcuser        29

nfsnobody      65534

xfs            43

haldaemon      68

avahi-autoipd  100

oldboy         500

mysql          501

nginx          502

nagios         503

disdata        999

ayibang        1000

liujianzuo     1001

 

End應用 添加表尾

[root@centos5 ceshi]# awk -F: 'BEGIN{print "USERNAME       UID"} {$3>=500;printf "%-15s%s\n",$1,$3}END{printsswd "END"}' /etc/passwd          

USERNAME       UID

root           0

bin            1

daemon         2

adm            3

lp             4

sync           5

shutdown       6

halt           7

mail           8

news           9

uucp           10

operator       11

games          12

gopher         13

ftp            14

nobody         99

nscd           28

vcsa           69

pcap           77

ntp            38

dbus           81

avahi          70

rpc            32

mailnull       47

smmsp          51

oprofile       16

sshd           74

rpcuser        29

nfsnobody      65534

xfs            43

haldaemon      68

avahi-autoipd  100

oldboy         500

mysql          501

nginx          502

nagios         503

disdata        999

ayibang        1000

liujianzuo     1001

END

 

 

 

BEGIN 賦值

[root@centos5 ceshi]# awk -F : '{print $1}' /etc/passwd |head -1

root

[root@centos5 ceshi]# awk -v FS=: '{print $1}' /etc/passwd |head -1

root

[root@centos5 ceshi]# awk 'BEGIN{FS=":"}{print $1}' /etc/passwd |head -1           

root

 

控制語句

 

若是if後面是好幾個條件應該用花括號擴起來

 

If案例

[root@centos5 ~]# awk -F: -v sum=0 '{if ($3>=500) sum++}END{print sum}' /etc/passwd

8

[root@centos5 ~]# awk -F: '{if ($3>=500) print $NF}' /etc/passwd 

/sbin/nologin

/bin/bash

/sbin/nologin

/sbin/nologin

/sbin/nologin

/bin/bash

/bin/bash

/bin/bash

[root@centos5 ~]# awk -F: '{if ($3>=500) print $NF}' /etc/passwd|wc -l

8

 

[root@centos5 ceshi]# awk -F: '{if ($3 == 0) print $1,"Admin";else print $1,"Comman user"}' /etc/passwd

root Admin

bin Comman user

daemon Comman user

adm Comman user

lp Comman user

sync Comman user

shutdown Comman user

halt Comman user

mail Comman user

news Comman user

uucp Comman user

operator Comman user

games Comman user

gopher Comman user

ftp Comman user

nobody Comman user

nscd Comman user

vcsa Comman user

pcap Comman user

ntp Comman user

dbus Comman user

avahi Comman user

rpc Comman user

mailnull Comman user

smmsp Comman user

oprofile Comman user

sshd Comman user

rpcuser Comman user

nfsnobody Comman user

xfs Comman user

haldaemon Comman user

avahi-autoipd Comman user

oldboy Comman user

mysql Comman user

nginx Comman user

nagios Comman user

disdata Comman user

ayibang Comman user

liujianzuo Comman user

 

 

While案例

[root@centos5 ~]# awk -F: '{i=1;while (i<=3) {print $i;i++}}' /etc/passwd  

root

x

0

bin

x

1

daemon

x

2

adm

x

3

lp

x

4

sync

x

5

shutdown

x

6

halt

x

7

mail

x

8

news

x

9

uucp

x

10

operator

x

11

games

x

12

gopher

x

13

ftp

x

14

nobody

x

99

nscd

x

28

vcsa

x

69

pcap

x

77

ntp

x

38

dbus

x

81

avahi

x

70

rpc

x

32

mailnull

x

47

smmsp

x

51

oprofile

x

16

sshd

x

74

rpcuser

x

29

nfsnobody

x

65534

xfs

x

43

haldaemon

x

68

avahi-autoipd

x

100

oldboy

x

500

mysql

x

501

nginx

x

502

nagios

x

503

disdata

x

999

ayibang

x

1000

liujianzuo

x

1001

Awk能夠加pattion 模式的意思,若是不匹配pattion意指其會每行都匹配。

[oldboy@centos5 ~]$ awk -F: '$1 !~ /^root/{i=1;while (i<=2) {print $i;i++}}' /etc/passwd

bin

x

daemon

x

adm

x

lp

x

sync

x

shutdown

x

halt

x

mail

x

news

x

uucp

x

operator

x

games

x

gopher

x

ftp

x

nobody

x

nscd

x

vcsa

x

pcap

x

ntp

x

dbus

x

avahi

x

rpc

x

mailnull

x

smmsp

x

oprofile

x

sshd

x

rpcuser

x

nfsnobody

x

xfs

x

haldaemon

x

avahi-autoipd

x

oldboy

x

mysql

x

nginx

x

nagios

x

disdata

x

ayibang

x

liujianzuo

X

例如我想取第第奇數個字段。咱們遞增i+=2便可

[oldboy@centos5 ~]$ awk -F: '$3 >= 500{i=1;while (i<=4) {print $i;i+=2}}' /etc/passwd            

Nfsnobody  #第一列

65534   #第三列

Oldboy #第一列

500  #第三列

mysql

501

nginx

502

nagios

503

disdata

999

ayibang

1000

liujianzuo

1001

 

do-while 不管條件如何,首先會循環一遍,當條件一知足就會退出

 

 

用awk的while循環計算1+。。。+100

 

[root@centos5 awk]# awk 'BEGIN{i=1;while (i<=100) {sum+=i;print sum;i++}}' |tail -1

5050

awk 'BEGIN{i=1;do {sum+=i;print sum;i++}while(i<=100)}'|tail -1

5050

awk 'BEGIN{i=1;do {sum=sum+i;print sum;i++}while(i<=100)}'|tail -1  

5050

 

 

awk 'BEGIN{i=1;do {sum+=i;i++}while(i<=100) print sum}' 

【元嬰】北京-吳兆 2015/1/11 17:53:30

循環中不輸出,最後輸出結構就好了…… 

 

 

 

 

 

For循環案例

cat filename | nawk -F " "  '{for (i=4;i<=NF;i++)printf("%s ", $i);print ""}'  字段不換行 printf

 

[root@centos5 awk]# awk -F: '$3>=500{for (i=1;i<=NF;i+=2) print $i}' /etc/passwd 

awk -F: '$3>=500{for (i=1;i<=NF;i+=2) printf("%s ", $i);print ""}' /etc/passwd 

 

nfsnobody

65534

Anonymous NFS User

/sbin/nologin

oldboy

500

 

/bin/bash

mysql

501

 

/sbin/nologin

nginx

502

 

/sbin/nologin

nagios

503

 

/sbin/nologin

disdata

999

 

/bin/bash

ayibang

1000

 

/bin/bash

liujianzuo

1001

 

/bin/bash

for打印第奇數個字段

[root@centos5 awk]# awk -F: '$3>=500{for (i=1;i<=5;i+=2) print $i}' /etc/passwd  

nfsnobody

65534

Anonymous NFS User

oldboy

500

 

mysql

501

 

nginx

502

 

nagios

503

 

disdata

999

 

ayibang

1000

 

liujianzuo

1001

Awk 的For循環的1加到100

[root@centos5 awk]# awk 'BEGIN{for (i=i;i<=100;i++) {j=j+i;print j}}'|tail -1

5050

 

[root@ayibang-server /server/scripts]# awk 'BEGIN{j=0;for (i=1;i<=100;i++) j+=i;{print j}}'
5050

 

 

 

 

 

 

 

 

Awk的內置變量

 

內置變量

    如下爲awk內置變量:

          ARGC        命令行參數個數

          FILENAME    當前輸入文檔的名稱

          FNR        當前輸入文檔的當前記錄編號,尤爲當有多個輸入文檔時有用

          NR        輸入流的當前記錄編號

          NF        當前記錄的字段個數

          FS        字段分隔符

          OFS        輸出字段分隔符,默認爲空格

          ORS        輸出記錄分隔符,默認爲換行符\n

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

示例:

Awk的引用shell中的參數

[liujianzuo@w2 scripts]$  for n in {06..26};do for i in `ls -l /data1/logs/qr* |awk '{print $NF}'`;do wc -l $i|awk -F . '$NF ~ /201507'${n}'/{print $0}';done;done                                  1 /data1/logs/qrscene_51pro_gz.log.20150707

6 /data1/logs/qrscene_51pro_hz.log.20150707

2 /data1/logs/qrscene_51pro_nj.log.20150707

3 /data1/logs/qrscene_51pro_qd.log.20150707

1 /data1/logs/qrscene_51pro_sh.log.20150707

6 /data1/logs/qrscene_51pro_wh.log.20150707

1 /data1/logs/qrscene_51pro_xa.log.20150707

1 /data1/logs/qrscene_51pro_zz.log.20150707

4 /data1/logs/qrscene_cq_dm.log.20150707

5 /data1/logs/qrscene_cq_sl.log.20150707

17 /data1/logs/qrscene_cs_dm.log.20150707

1 /data1/logs/qrscene_gz_dm.log.20150707

1 /data1/logs/qrscene_gz_szi.log.20150707

6 /data1/logs/qrscene_hz_dm.log.20150707

9 /data1/logs/qrscene_mlyh.log.20150707

2 /data1/logs/qrscene_nj_dm.log.20150707

3 /data1/logs/qrscene_nj_sl.log.20150707

1 /data1/logs/qrscene_qd_szi.log.20150707

1 /data1/logs/qrscene_xa_szi.log.20150707

14 /data1/logs/qrscene_xiaomi.log.20150707

26 /data1/logs/qrscene_xz.log.20150707

4 /data1/logs/qrscene_zz_dm.log.20150707

3 /data1/logs/qrscene_15suit.log.20150708

5 /data1/logs/qrscene_51pro_bj.log.20150708

1 /data1/logs/qrscene_51pro_gz.log.20150708

5 /data1/logs/qrscene_51pro_hz.log.20150708

19 /data1/logs/qrscene_51pro_qd.log.20150708

1 /data1/logs/qrscene_51pro_wh.log.20150708

。。。。。略去n行

 

 

http://oldboy.blog.51cto.com/2561410/760192 

問題爲:

4)已知:/etc/hosts的內容爲

192.168.1.11  oldboy11.etiantian.org

192.168.1.21  oldboy21.etiantian.org

192.168.1.31  oldboy31.etiantian.org

#192.168.1.111  oldboy111.etiantian.org

請用shell腳本實現,怎麼才能在輸入IP後找到/etc/hosts裏對應的惟一的hostname?

解答:

法1)腳本過濾法

[root@old_boy scripts]# cat judgehost.sh   

#!/bin/bash  

echo "please input ip address:" 

read ip  

[ -n "`grep "$ip " /etc/hosts`" ] && \  #注意前面的過濾條件結尾帶有空格。  

echo "The hostname is: `grep "$ip " /etc/hosts |awk '{print $2}'`" || \  

echo "The ip is invalid" 

 提示:

1)這是一個grep過濾加條件判斷的實現語法:

2)條件判斷語法爲[ -n "ddd" ] && echo 1 || echo 0

3)[ -n "`grep "$ip " /etc/hosts`" ] && \  #注意前面的過濾條件結尾帶有空格。這裏啊,是爲了排除下面的重複狀況

 192.168.1.11  oldboy11.etiantian.org

 192.168.1.111  oldboy111.etiantian.org

----------------我是每種方法分隔符---------------

法2)腳本精確匹配法:

#!/bin/bash  

#author oldboy  

#qq 31333741  

#judge input  

if [ $# -ne 1 ]  

  then 

    echo "input error!" 

    exit 1  

fi  

 

flag=0  

exec < /etc/hosts  

while read line  

do  

 if [ "$1" = "`echo $line|awk '{print $1}'`" ]  

   then 

       flag=1  

       echo "the $1 's hostname is `echo $line|awk '{print $2}'`"   

       break;  

 fi  

done   

[ $flag -eq 0 ] && echo " sorrry,not find $1 's hostname!" 

 

提示:此題,請你們學習while的用法及設置flag的思路。

執行結果:

[root@old_boy scripts]# sh oldboy.sh 192.168.1.11

the 192.168.1.11 's hostname is oldboy11.etiantian.org

[root@old_boy scripts]# sh oldboy.sh 192.168.1.21

the 192.168.1.21 's hostname is oldboy21.etiantian.org

[root@old_boy scripts]# sh oldboy.sh 192.168.1.311

 sorrry,not find 192.168.1.311 's hostname!

----------------我是每種方法分隔符---------------

 

特別提示:下面的方法中,老男孩老師大量的使用了awk的不一樣方法來實現一樣的功能,來告訴你們,awk是很強大的, 但願同窗們能按照老師的教學要求精通之。

法3)awk精確匹配:

準備:

[root@old_boy scripts]# tail -4 /etc/hosts

192.168.1.11  oldboy11.etiantian.org

192.168.1.111  oldboy111.etiantian.org

192.168.1.21  oldboy21.etiantian.org

192.168.1.31  oldboy31.etiantian.org

腳本:

[root@old_boy scripts]# cat awkhost1.sh   

awk 'BEGIN {a="'$1'"} {if($1==a) print $2; }' /etc/hosts  

執行結果:

[root@old_boy scripts]# sh awkhost1.sh 192.168.1.21

oldboy21.etiantian.org

[root@old_boy scripts]# sh awkhost1.sh 192.168.1.31

oldboy31.etiantian.org

[root@old_boy scripts]# sh awkhost1.sh 192.168.1.11

oldboy11.etiantian.org

提示:注意a="'$1'"的用法,$1爲命令行傳參。awk程序中調用系統變量的方法a="'$1'"。

----------------我是每種方法分隔符---------------

法4)awk精確匹配法

[root@old_boy scripts]# cat awkhost2.sh   

awk '{if($1=="'$1'") print $2}' /etc/hosts  

執行結果:

[root@old_boy scripts]# awkhost2.sh 192.168.1.11

oldboy11.etiantian.org

[root@old_boy scripts]# awkhost2.sh 192.168.1.21

oldboy21.etiantian.org

[root@old_boy scripts]# awkhost2.sh 192.168.1.311

----------------我是每種方法分隔符---------------

法5)awk過濾法

[root@old_boy scripts]# cat awkhost4.sh   

awk '/'"${1} "'/''{print $2}' /etc/hosts  

執行結果:  

[root@old_boy scripts]# awkhost4.sh 192.168.1.21  

oldboy21.etiantian.org  

[root@old_boy scripts]# awkhost4.sh 192.168.1.11  

oldboy11.etiantian.org  

[root@old_boy scripts]# awkhost4.sh 192.168.1.31  

oldboy31.etiantian.org  

提示:除了語法外,這道題有個學問,就是過濾時傳參結尾要帶個空格,這樣才能過濾重複IP的狀況  

如:  

 192.168.1.11  oldboy11.etiantian.org  

 192.168.1.111  oldboy111.etiantian.org 

----------------我是每種方法分隔符---------------

法6)awk過濾法

[root@old_boy scripts]# cat awkhost5.sh   

awk '{if($1~/'$1'/) print $2}'  /etc/hosts ##若是文件第一列包含命令行第一個參數字符則打印第二列  

執行結果:  

[root@old_boy scripts]# awkhost5.sh 192.168.1.31  

oldboy31.etiantian.org  

[root@old_boy scripts]# awkhost5.sh 192.168.1.11  

oldboy11.etiantian.org  

oldboy111.etiantian.org ------>這裏有bug了。  

[root@old_boy scripts]# awkhost5.sh 192.168.1.21  

oldboy21.etiantian.org  

改進下來排除bug:  

[root@old_boy scripts]# cat awkhost5-1.sh   

awk '{if($1~/'$1' /) print $2}'  /etc/hosts ==>用上面加空格的思路不對。  

[root@old_boy scripts]# cat awkhost5-1.sh   

awk '{if($1~/'$1'$/) print $2}'  /etc/hosts #增長一個正則表達式$  

執行結果:  

[root@old_boy scripts]# awkhost5-1.sh 192.168.1.21  

oldboy21.etiantian.org  

[root@old_boy scripts]# awkhost5-1.sh 192.168.1.11  

oldboy11.etiantian.org  

[root@old_boy scripts]# awkhost5-1.sh 192.168.1.31  

oldboy31.etiantian.org 

----------------我是每種方法分隔符---------------

法7)awk -v精確匹配法

 

命令行測試:  

[root@old_boy scripts]# awk -v p=192.168.1.21 '$1 == p{print $2}' /etc/hosts  

oldboy21.etiantian.org  

[root@old_boy scripts]# awk -v p=192.168.1.11 '$1 == p{print $2}' /etc/hosts  

oldboy11.etiantian.org  

[root@old_boy scripts]# awk -v p=192.168.1.11 '$1 == p {print $2}' /etc/hosts  

oldboy11.etiantian.org  

實際腳本: 

[root@old_boy scripts]# cat awkhost6.sh   

#!/bin/bash  

#p=$1  

#awk -v p="$p" '$1 == p{print $2}' /etc/hosts  

awk -v p="$1" '$1 == p{print $2}' /etc/hosts 

執行結果:

[root@old_boy scripts]# sh  awkhost6.sh  192.168.1.11

oldboy11.etiantian.org

[root@old_boy scripts]# sh  awkhost6.sh  192.168.1.21

oldboy21.etiantian.org

提示:

1)傳參非awk程序,所以寫法p="$1"

2)man awk

       -v var=val

       --assign var=val

              Assign the value val to the variable var, before execution of the program begins.   Such  vari-

              able values are available to the BEGIN block of an AWK program.

----------------我是每種方法分隔符---------------

法8:精確匹配簡單的寫法

[root@old_boy scripts]# cat awkhost9.sh   

awk  '$1 == "'$1'" {print $2}' /etc/hosts  

執行結果:  

[root@old_boy scripts]# sh awkhost9.sh  192.168.1.11  

oldboy11.etiantian.org  

[root@old_boy scripts]# sh awkhost9.sh  192.168.1.21  

oldboy21.etiantian.org  

[root@old_boy scripts]# sh awkhost9.sh  192.168.1.31  

oldboy31.etiantian.org  

特別提示:這裏老男孩老師大量的使用了awk的不一樣方法來實現一樣的功能,很強大吧,  

但願同窗們能按照老師的教學要求精通之。 

 

 

Awk的 數組

 

 

 

數組就是變量的即集合體

 

Shell中的打印 echo ${A["x"]} 須要${}才能輸出變量,而awk則不用

下標能夠是任意字符,可是咱們要將字符用引號引發來,以避免被誤認爲變量

以下

[root@centos5 ~]# awk 'BEGIN{A[x]='hello';A[y]='world';print A[x]}'

 

[root@centos5 ~]# awk 'BEGIN{A["x"]='hello';A["y"]='world';print A[x],A["y"]}'   

 

[root@centos5 ~]# awk 'BEGIN{A["x"]="hello";A["y"]="world";print A[x],A["y"]}'    

 world

[root@centos5 ~]# awk 'BEGIN{A["x"]="hello";A["y"]="world";print A["x"],A["y"]}'

hello world

 

 

 

 

 

Awk的數組不能跟shell的數組同樣,不能一一遍歷,它的元素不都是數字,有多是字符串或者字段

 

第二個是for循環是awk的遍歷,這裏面的ARRAY是數組,A是咱們定義的變量是數組的下標數字0 1 2 3 。。。  A保存的是咱們數組ARRAY的下標名字

 

例如

[root@centos5 ~]# awk 'BEGIN{A["x"]="hello";A["y"]="world";for (B in A) print A[B]}'   #這裏的B是定義的變量就是A數組的下標號,咱們遍歷A數組,打印全部的元素。B保存的是A數組的下標名字                           

hello

world

 

 

 

例一:awk過濾統計tcp鏈接狀態的個數

Tcp狀態有好多種,最後一列,咱們用awk實現統計每種狀態的鏈接數 後面有解釋

[root@centos5 ~]# netstat -ant

Active Internet connections (servers and established)

Proto Recv-Q Send-Q Local Address               Foreign Address             State      

tcp        0      0 0.0.0.0:2049                0.0.0.0:*                   LISTEN      

tcp        0      0 0.0.0.0:5666                0.0.0.0:*                   LISTEN      

tcp        0      0 127.0.0.1:199               0.0.0.0:*                   LISTEN      

tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      

tcp        0      0 0.0.0.0:624                 0.0.0.0:*                   LISTEN      

tcp        0      0 0.0.0.0:22929               0.0.0.0:*                   LISTEN      

tcp        0      0 0.0.0.0:52113               0.0.0.0:*                   LISTEN      

tcp        0      0 0.0.0.0:1012                0.0.0.0:*                   LISTEN      

tcp        0      0 192.168.92.132:52113        192.168.92.1:49262          ESTABLISHED 

tcp        0      0 :::52113                    :::*                        LISTEN

 

解釋例子

Awk的數組組成:數組名字,數組下標,數組元素,數組元素的值。

S[$NF]++ 意思是咱們這個數組S,咱們取最後一列做爲這個數組的下標,所以這個數組就是S[LISTEN] S[ESTABLISHED],每讀取一行,相同元素會疊加

 

這裏A是數組S的下標名稱,而數組S的下標名稱是TIME_WAIT  CLOSE_WAIT   FIN_WAIT1  ESTABLISHED  等等。For循環是遍歷的這幾種,因此A就表明這幾個名稱,而S[A]則表明數組元素的值

 

[ayibang@db2 ~]$ netstat -ant|awk '$1~/tcp/{S[$NF]++}END{for (A in S) print A,S[A]}' 

TIME_WAIT 1789

CLOSE_WAIT 38

FIN_WAIT1 6

ESTABLISHED 94

SYN_RECV 3

LAST_ACK 3

LISTEN 23

 

或者用ss命令取值

[ayibang@db2 ~]$ ss -ant |awk '{S[$1]++}END{for (A in S) printf "%4s,%4s\n",S[A],A}'

   8,LAST-ACK

   3,SYN-RECV

 292,ESTAB

   1,State

   4,FIN-WAIT-1

   3,CLOSING

   8,FIN-WAIT-2

6469,TIME-WAIT

  41,CLOSE-WAIT

  23,LISTEN

例二:awk 完成/etc/passwd 取最後一個字段同種shell解釋類型的個數,排除空行

[root@centos5 ~]# awk -F: '$NF!~/^$/{SHELL[$NF]++}END{for(A in SHELL) printf "%16s:%s\n",A,SHELL[A]}' /etc/passwd 

  /sbin/shutdown:1

       /bin/bash:5

   /sbin/nologin:30

      /sbin/halt:1

       /bin/sync:1

 

 

 

例三:查看訪問日誌ip;

[root@db2 logs]# awk '{IP[$1]++}END{for (A in IP) printf "%20s:%5s\n",A,IP[A]}' access_www.log |sort -rn|head

          223.9.2.89:   37

      223.68.131.168:   31

       223.243.41.89:    1

      223.240.233.91:   34

      223.223.194.23:   50

     223.223.194.215:   16

      223.167.19.183:   65

     223.166.112.132:    1

        223.104.5.30:   69

         223.104.5.2:    2

Awik的內置函數

 

例一 :統計客戶端鏈接80端口的ip個數,netstat 的第五列 (判斷黑客攻擊的統計)

split($5,client,":")含義以下

ه內置函數split 先把第五個字段,以:爲分隔符,切割新的字段,保存成client數組,

IP[client[1]]++}END{for (i in IP){print IP[i],i}}'

以新的IP數組,client數組第一列爲新數組IP下標,最後作作求和,統計個數 

split是函數  用小括號…………

 

[root@db2 ~]# netstat -ant|awk '/:80/{split($5,client,":");IP[client[1]]++}END{for (i in IP){print IP[i],i}}'|sort -rn |head

10 116.247.112.153

6 210.22.62.180

6 123.125.65.237

5 123.138.215.24

3 221.237.44.110

3 111.202.0.53

3 106.2.195.214

2 117.79.81.51

2 101.80.175.17

2 0.0.0.0

 

 

 

 

 

 

 

 

 

 

Awk練習 

需求:awk實現每一行對應字段的數字相加

a文件
11 23
13 23
43 56
b文件
11 43
45 455
32 23


輸出結果以下
22 66
58 478
75 79

 

 

解答:

awk '{a[FNR]+=$1;b[FNR]+=$2} END{for(i in a){print a[i],b[i]}}' cc1.log cc2.log 

 

awk '{n=FNR;a[n]+=$1;b[n]+=$2} END{for(i=1;i<=n;i++){print a[i],b[i]}}' cc1.log cc2.log

 

awk '{n=FNR;a[n]+=$1;b[n]+=$2; if(NR > n) print a[n],b[n]}' cc1.log cc2.log   

 

awk '{n=FNR;a[n]+=$1;b[n]+=$2} NR > n {print a[n],b[n]}' cc1.log cc2.log

 

awk '{if(NR == FNR){a[NR]=$1;b[NR]=$2}else{print $1+a[FNR],$2+b[FNR]}}' cc1.log cc2.log 

 

 

awk 'NR==FNR {a[NR]=$1;b[NR]=$2;next} {print $1+a[FNR],$2+b[FNR]}' cc1.log cc2.log 

 

paste cc1.log cc2.log |awk '{print $1+$3,$2+$4}'

 

awk 'NR == FNR{a[i]=$1;b[i]=$2;i++} NR>FNR{print $1+a[j],$2+b[j];j++}' cc1.log cc2.log 

 

 

 

 

 

Awk sed 練習

20150418週末小題

原始數據:

17/Apr/2015:09:29:24 +0800

17/Apr/2015:09:30:26 +0800

17/Apr/2015:09:31:56 +0800

18/Apr/2015:09:34:12 +0800

18/Apr/2015:09:35:23 +0800

19/Apr/2015:09:23:34 +0800

19/Apr/2015:09:22:21 +0800

20/Apr/2015:09:45:22 +0800

指望結果:

2015-04-17 09:29:24+0800

2015-04-17 09:30:26+0800

2015-04-17 09:31:56+0800

2015-04-18 09:34:12+0800

2015-04-18 09:35:23+0800

2015-04-19 09:23:34+0800

2015-04-19 09:22:21+0800

2015-04-20 09:45:22+0800

 

解決實踐:來自運維21期悠久之翼 羣內分享

[root@web01 ~]# cat oldboy.txt 

17/Apr/2015:09:29:24 +0800

17/Apr/2015:09:30:26 +0800

17/Apr/2015:09:31:56 +0800

18/Apr/2015:09:34:12 +0800

18/Apr/2015:09:35:23 +0800

19/Apr/2015:09:23:34 +0800

19/Apr/2015:09:22:21 +0800

20/Apr/2015:09:45:22 +0800

 

 

[root@web01 ~]# awk '{sub(/Apr/,"04");split($0,array,"[/: ]") ;printf("%s-%s-%s %s:%s:%s%s\n",array[3],array[2],array[1],array[4],array[5],array[6],array[7])}' oldboy.txt 

2015-04-17 09:29:24+0800

2015-04-17 09:30:26+0800

2015-04-17 09:31:56+0800

2015-04-18 09:34:12+0800

2015-04-18 09:35:23+0800

2015-04-19 09:23:34+0800

2015-04-19 09:22:21+0800

2015-04-20 09:45:22+0800

 

1. sub函數

 

[root@nhserver1 10]# echo "a b c 2011-11-22 a:d" | awk 'sub(/-/,"",$4)'

a b c 201111-22 a:d

 

 

2. gsub函數

 

[root@nhserver1 10]# echo "a b c 2011-11-22 a:d" | awk 'gsub(/-/,"",$4)'

a b c 20111122 a:d

 

 

sub函數只實現第一個位置的替換,gsub函數實現全局的替換。

Split切割是第一列下表是1

 

 

[root@web01 ~]# sed -nr 's#(..)/(...)/(....):(..):(..):(..) (.*)#\3-\2-\1 \4:\5:\6\7#;s#Apr#04#p' oldboy.txt 

2015-04-17 09:29:24+0800

2015-04-17 09:30:26+0800

2015-04-17 09:31:56+0800

2015-04-18 09:34:12+0800

2015-04-18 09:35:23+0800

2015-04-19 09:23:34+0800

2015-04-19 09:22:21+0800

2015-04-20 09:45:22+0800

 

. 是一個字符, s是替換  p打印

 

Sed 擴展

在編寫shell腳本的過程當中,咱們常常須要使用sed流編輯器和awk對文本文件進行處理。

1、什麼是sed

    sed 是一種在線編輯器,它一次處理一行內容。sed是非交互式的編輯器。它不會修改文件,除非使用shell重定向來保存結果。默認狀況下,全部的輸出行都被打印到屏幕上。

 

2、sed的處理過程

    sed編輯器逐行處理文件(或輸入),並將結果發送到屏幕。具體過程以下:首先sed把當前正在處理的行保存在一個臨時緩存區中(也稱爲模式空間),而後處理臨時緩衝區中的行,完成後把該行發送到屏幕上。sed每處理完一行就將其從臨時緩衝區刪除,而後將下一行讀入,進行處理和顯示。處理完輸入文件的最後一行後,sed便結束運行。

   前面說到sed不會修改文件,那麼如今咱們能夠知道是爲何了?是由於sed把每一行都存在臨時緩衝區中,對這個副本進行編輯,因此不會修改原文件。

補充知識:

    在使用sed的過程當中,咱們常常會聽到「定址」,那麼什麼是「定址」呢?

    定址用於決定對哪些行進行編輯。地址的形式能夠是數字、正則表達式、或兩者的結合。若是沒有指定地址,sed將處理輸入文件的全部行。

一、地址是一個數字,則表示行號;是「$"符號,則表示最後一行。

例如:

[plain] view plaincopy

  1. sed -n '3p' datafile   #只打印第三行  

 

二、只顯示指定行範圍的文件內容

例如:

[plain] view plaincopy

  1. sed -n '100,200p' mysql_slow_query.log  # 只查看文件的第100行到第200行  

 

三、地址是逗號分隔的,那麼須要處理的地址是這兩行之間的範圍(包括這兩行在內)。範圍能夠用數字、正則表達式、或兩者的組合表示。

例如:

[plain] view plaincopy

  1. sed '2,5d' datafile  
  2. #刪除第二到第五行  
  3. sed '/My/,/You/d' datafile  
  4. #刪除包含"My"的行到包含"You"的行之間的行  
  5. sed '/My/,10d' datafile  
  6. #刪除包含"My"的行到第十行的內容  

 

3、sed命令和選項

sed命令告訴sed如何處理由地址指定的各輸入行,若是沒有指定地址則處理全部的輸入行。

一、sed命令

 

 命令

 功能

 a\

 在當前行後添加一行或多行。多行時除最後一行外,每行末尾需用「\」續行

 c\

 用此符號後的新文本替換當前行中的文本。多行時除最後一行外,每行末尾需用"\"續行

 i\

 在當前行以前插入文本。多行時除最後一行外,每行末尾需用"\"續行

 d

 刪除行

 h

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

 H

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

 g

 把暫存緩衝區裏的內容複製到模式空間,覆蓋原有的內容

 G

 把暫存緩衝區的內容追加到模式空間裏,追加在原有內容的後面

 l

 列出非打印字符

 p

 打印行

 n

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

 q

 結束或退出sed

 r

 從文件中讀取輸入行

 !

 對所選行之外的全部行應用命令

 s

 用一個字符串替換另外一個

 g

 在行內進行全局替換

 w

 將所選的行寫入文件

 x

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

 y

 將字符替換爲另外一字符(不能對正則表達式使用y命令)

 

二、sed選項

 

 選項

 功能

 -e

 進行多項編輯,即對輸入行應用多條sed命令時使用

 -n

 取消默認的輸出

 -f

 指定sed腳本的文件名

 

4、正則表達式元字符

    與grep同樣,sed也支持特殊元字符,來進行模式查找、替換。不一樣的是,sed使用的正則表達式是括在斜槓線"/"之間的模式。

    若是要把正則表達式分隔符"/"改成另外一個字符,好比o,只要在這個字符前加一個反斜線,在字符後跟上正則表達式,再跟上這個字符便可。

例如:

[plain] view plaincopy

  1. sed -n '\o^Myop' datafile  


經常使用的正則表達式以下:

 元字符

 功能

 示例

 ^

 行首定位符

 /^my/ 匹配全部以my開頭的行

 $

 行尾定位符

 /my$/ 匹配全部以my結尾的行

 .

 匹配除換行符之外的單個字符

 /m..y/ 匹配包含字母m,後跟兩個任意字符,再跟字母y的行

 *

 匹配零個或多個前導字符

 /my*/ 匹配包含字母m,後跟零個或多個y字母的行

 []

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

 /[Mm]y/ 匹配包含My或my的行

 [^]

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

 /[^Mm]y/ 匹配包含y,但y以前的那個字符不是M或m的行

 ..

 保存已匹配的字符

 1,20s/youself/\1r/ 標記元字符之間的模式,並將其保存爲標籤1,以後可使用\1來引用它。最多能夠定義9個標籤,從左邊開始編號,最左邊的是第一個。此例中,對第1到第20行進行處理,you被保存爲標籤1,若是發現youself,則替換爲your。

 &

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

 s/my/**&**/  符號&表明查找串。my將被替換爲**my**

 \<

 詞首定位符

 /\<my/ 匹配包含以my開頭的單詞的行

 \>

 詞尾定位符

 /my\>/ 匹配包含以my結尾的單詞的行

 x\{m\}

 連續m個x

 /9\{5\}/匹配包含連續5個9的行

 x\{m,\}

 至少m個x

 /9\{5,\}/ 匹配包含至少連續5個9的行

 x\{m,n\}

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

 /9\{5,7\}/ 匹配包含連續5到7個9的行

 

5、sed的退出狀態

    sed不向grep同樣,無論是否找到指定的模式,它的退出狀態都是0。只有當命令存在語法錯誤時,sed的退出狀態纔不是0。

6、經常使用範例

一、p命令

    命令p用於顯示模式空間的內容。默認狀況下,sed把輸入行打印在屏幕上,選項-n用於取消默認的打印操做。當選項-n和命令p同時出現時,sed可打印選定的內容。

例子:

[plain] view plaincopy

  1. (1)sed '/my/p' datafile  
  2. #默認狀況下,sed把全部輸入行都打印在標準輸出上。若是某行匹配模式my,p命令將把該行另外打印一遍。  
  3. (2)sed -n '/my/p' datafile  
  4. #選項-n取消sed默認的打印,p命令把匹配模式my的行打印一遍。  

 

二、d命令

    命令d用於刪除輸入行。sed先將輸入行從文件複製到模式空間裏,而後對該行執行sed命令,最後將模式空間裏的內容顯示在屏幕上。若是發出的是命令d,當前模式空間裏的輸入行會被刪除,不被顯示。

例子:

[plain] view plaincopy

  1. (1)sed '$d' datafile  
  2. #刪除最後一行,其他的都被顯示  
  3. (2)sed '/my/d' datafile  
  4. #刪除包含my的行,其他的都被顯示  

 

三、s命令

例子:

[plain] view plaincopy

  1. (1)sed 's/^My/You/g' datafile  
  2. #命令末端的g表示在行內進行全局替換,也就是說若是某行出現多個My,全部的My都被替換爲You。  
  3. (2)sed -n '1,20s/My$/You/gp' datafile  
  4. #取消默認輸出,處理1到20行裏匹配以My結尾的行,把行內全部的My替換爲You,並打印到屏幕上。  
  5. (3)sed 's#My#Your#g' datafile  
  6. #緊跟在s命令後的字符就是查找串和替換串之間的分隔符。分隔符默認爲正斜槓,但能夠改變。不管什麼字符(換行符、反斜線除外),只要緊跟s命令,就成了新的串分隔符。  


 

四、e選項

   -e是編輯命令,用於sed執行多個編輯任務的狀況下。在下一行開始編輯前,全部的編輯動做將應用到模式緩衝區中的行上。

例子:

[plain] view plaincopy

  1. sed -e '1,10d' -e 's/My/Your/g' datafile  
  2. #選項-e用於進行多重編輯。第一重編輯刪除第1-3行。第二重編輯將出現的全部My替換爲Your。由於是逐行進行這兩項編輯(即這兩個命令都在模式空間的當前行上執行),因此編輯命令的順序會影響結果。  

 

五、r命令

r命令是讀命令。sed使用該命令將一個文本文件中的內容加到當前文件的特定位置上。

例如:

[plain] view plaincopy

  1. sed '/My/r introduce.txt' datafile  
  2. #若是在文件datafile的某一行匹配到模式My,就在該行後讀入文件introduce.txt的內容。若是出現My的行不止一行,則在出現My的各行後都讀入introduce.txt文件的內容。  

 

六、w命令

例子:

[plain] view plaincopy

  1. sed -n '/hrwang/w me.txt' datafile  

 

七、a\ 命令

    a\ 命令是追加命令,追加將添加新文本到文件中當前行(即讀入模式緩衝區中的行)的後面。所追加的文本行位於sed命令的下方另起一行。若是要追加的內容超過一行,則每一行都必須以反斜線結束,最後一行除外。最後一行將以引號和文件名結束。

例子:

[plain] view plaincopy

  1. sed '/^hrwang/a\  
  2. >hrwang and mjfan are husband\  
  3. >and wife' datafile  
  4. #若是在datafile文件中發現匹配以hrwang開頭的行,則在該行下面追加hrwang and mjfan are husband and wife  

 

八、i\ 命令

i\ 命令是在當前行的前面插入新的文本。

 

九、c\ 命令

sed使用該命令將已有文本修改爲新的文本。

 

十、n命令

sed使用該命令獲取輸入文件的下一行,並將其讀入到模式緩衝區中,任何sed命令都將應用到匹配行緊接着的下一行上。

例如:

[plain] view plaincopy

  1. sed '/hrwang/{n;s/My/Your/;}' datafile  

注:若是須要使用多條命令,或者須要在某個地址範圍內嵌套地址,就必須用花括號將命令括起來,每行只寫一條命令,或這用分號分割同一行中的多條命令。

 

十一、y命令

    該命令與UNIX/Linux中的tr命令相似,字符按照一對一的方式從左到右進行轉換。例如,y/abc/ABC/將把全部小寫的a轉換成A,小寫的b轉換成B,小寫的c轉換成C。

例如:

[plain] view plaincopy

  1. sed '1,20y/hrwang12/HRWANG^$/' datafile  
  2. #將1到20行內,全部的小寫hrwang轉換成大寫,將1轉換成^,將2轉換成$。  
  3. #正則表達式元字符對y命令不起做用。與s命令的分隔符同樣,斜線能夠被替換成其它的字符。  

 

十二、q命令

    q命令將致使sed程序退出,再也不進行其它的處理。

[plain] view plaincopy

  1. sed '/hrwang/{s/hrwang/HRWANG/;q;}' datafile  

 

1三、h命令和g命令

爲了更好說明這兩個命令,咱們先建立以下的文本文件:

[plain] view plaincopy

  1. #cat datafile  
  2. My name is hrwang.  
  3. Your name is mjfan.  
  4. hrwang is mjfan's husband.  
  5. mjfan is hrwang's wife.  

 

[plain] view plaincopy

  1. sed -e '/hrwang/h' -e '$G' datafile  
  2. sed -e '/hrwang/H' -e '$G' datafile  
  3. #經過上面兩條命令,你會發現h會把原來暫存緩衝區的內容清除,只保存最近一次執行h時保存進去的模式空間的內容。而H命令則把每次匹配hrwnag的行都追加保存在暫存緩衝區。  
  4. sed -e '/hrwang/H' -e '$g' datafile  
  5. sed -e '/hrwang/H' -e '$G' datafile  
  6. #經過上面兩條命令,你會發現g把暫存緩衝區中的內容替換掉了模式空間中當前行的內容,此處即替換了最後一行。而G命令則把暫存緩衝區的內容追加到了模式空間的當前行後。此處即追加到了末尾。  

 

補充知識點:sed特殊用法

[plain] view plaincopy

  1. sed -n '/root/w a.txt'    #將匹配行輸出到文件  
  2. sed '/root/r abc.txt' /etc/passwd #把abc.txt的文件內容讀入到root匹配行後  
  3. sed -n '/root/w a.txt'  
  4. sed -n '/root/{=;p}' /etc/passwd #打印行號和匹配root的行  
  5. sed -n '/root/{n;d}' /etc/passwd #將匹配root行的下一行刪除  
  6. sed -n '/root/{N;d}' /etc/passwd #將匹配root行和下一行都刪除  
  7. sed '22{h;d};23,33{H;d};44G' pass  

7、sed腳本編寫方法

一、從文件讀入命令

[plain] view plaincopy

  1. sed -f sed.sh  

sed.sh文件內容:

[plain] view plaincopy

  1. s/root/yerik/p  
  2. s/bash/csh/p  

 

二、直接運行腳本 ./sed.sh /etc/passwd

[plain] view plaincopy

  1. #!/bib/sed -f  
  2. s/root/yerik/p  
  3. s/bash/csh/p  

8、小技巧

一、用sed 輸出本身的IP 地址

[plain] view plaincopy

  1. ifconfig eth0 |sed '2p' |sed 's/^.*addr:/ /g' |sed 's/B.*$ / /g'  

 

二、在sed的命令行中引用shell變量時要使用雙引號,而不是一般所用的單引號。下面是一個根據name變量的內容來刪除named.conf文件中zone段的腳本:

name='zone\ "localhost"'

[plain] view plaincopy

  1. sed "/$name/,/};/d" named.conf   

 

三、保持和獲取:h命令和G命令

[plain] view plaincopy

  1. $ sed -e '/test/h' -e '$G example  

    在sed處理文件的時候,每一行都被保存在一個叫模式空間的臨時緩衝區中,除非行被刪除或者輸出被取消,不然全部被處理的行都將打印在屏幕上。接着模式空間被清空,並存入新的一行等待處理。在這個例子裏,匹配test的行被找到後,將存入模式空間,h命令將其複製並存入一個稱爲保持緩存區的特殊緩衝區內。第二條語句的意思是,當到達最後一行後,G命令取出保持緩衝區的行,而後把它放回模式空間中,且追加到如今已經存在於模式空間中的行的末尾。在這個例子中就是追加到最後一行。簡單來講,任何包含test的行都被複制並追加到該文件的末尾。

 

四、保持和互換:h命令和x命令

[plain] view plaincopy

  1. $ sed -e '/test/h' -e '/check/x' example   

   互換模式空間和保持緩衝區的內容。也就是把包含test與check的行互換。

 

 

9、練習

1,刪除文件每行的第一個字符。

[plain] view plaincopy

  1. sed -n 's/^.//gp' /etc/passwd  
  2. sed -nr 's/(.)(.*)/\2/p' /etc/passwd  

 

2,刪除文件每行的第二個字符。

[plain] view plaincopy

  1. sed -nr 's/(.)(.)(.*)/\1\3/p' /etc/passwd  

 

3,刪除文件每行的最後一個字符。

[plain] view plaincopy

  1. sed -nr 's/.$//p' /etc/passwd  
  2. sed -nr 's/(.*)(.)/\1/p' /etc/passwd  

 

4,刪除文件每行的倒數第二個字符。

[plain] view plaincopy

  1. sed -nr 's/(.*)(.)(.)/\1\3/p' /etc/passwd  

 

5,刪除文件每行的第二個單詞。

[plain] view plaincopy

  1. sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\2\3\5/p' /etc/passwd  

 

6,刪除文件每行的倒數第二個單詞。

[plain] view plaincopy

  1. sed -nr 's/(.*)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]*)/\1\2\4\5\6/p' /etc/samba/smb.conf  

 

7,刪除文件每行的最後一個單詞。

[plain] view plaincopy

  1. sed -nr 's/(.*)([^a-Z]+)([a-Z]+)([^a-Z]*)/\1\2\4/p' /etc/samba/smb.conf  

 

8,交換每行的第一個字符和第二個字符。

[plain] view plaincopy

  1. sed -nr 's/(.)(.)(.*)/\2\1\3/p' /etc/passwd  

 

9,交換每行的第一個單詞和第二個單詞。

[plain] view plaincopy

  1. sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\4\3\2\5/p' /etc/samba/smb.conf  

 

10,交換每行的第一個單詞和最後一個單詞。

[plain] view plaincopy

  1. sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\4\3\2\5/p' /etc/passwd  

 

11,刪除一個文件中全部的數字。

[plain] view plaincopy

  1. sed 's/[0-9]*//g' /etc/passwd  

 

12,刪除每行開頭的全部空格。

[plain] view plaincopy

  1. sed -n 's/^\ *//p' /etc/samba/smb.conf   
  2. sed -nr 's/( *)(.*)/\2/p' testp  

 

13,用製表符替換文件中出現的全部空格。

[plain] view plaincopy

  1. sed -n 's/\ /\t/gp' pass  

 

14,把全部大寫字母用括號()括起來。

[plain] view plaincopy

  1. sed -nr 's/([A-Z])/(&)/gp' testp   
  2. sed -n 's/[A-Z]/(&)/gp' testp  

15,打印每行3次。

[plain] view plaincopy

  1. sed 'p;p' pass  

 

16,隔行刪除。

[plain] view plaincopy

  1. sed -n '1~2p' pass  

 

17,把文件從第22行到第33行復制到第44行後面。

[plain] view plaincopy

  1. sed '1,21h;22h;23,33H;44G' pass  

 

18,把文件從第22行到第33行移動到第44行後面。

[plain] view plaincopy

  1. sed '22{h;d};23,33{H;d};44G' pass  

 

19,只顯示每行的第一個單詞。

[plain] view plaincopy

  1. sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)(.*)/\2/p' /etc/passwd  

 

20,打印每行的第一個單詞和第三個單詞。

[plain] view plaincopy

  1. sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\2--\4/p' /etc/passwd  

 

21,將格式爲    mm/yy/dd    的日期格式換成   mm;yy;dd

[plain] view plaincopy

  1. date +%m/%Y/%d |sed -n 's#/#;#gp'  

 

22, 逆向輸出

[plain] view plaincopy

  1. cat a.txt  
  2. ABC  
  3. DEF  
  4. XYZ  
  5. 輸出樣式變成  
  6. XYZ  
  7. DEF  
  8. ABC  
相關文章
相關標籤/搜索