Awk总结笔记

介绍

90年代 new awk :nawk

Linux 的是gawk 我们简化awk

用法

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

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

读入文本先切片如下 切5片

每片$n  整行$0

每行片数不一样

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的正则表达式匹配中,如果要使用外部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循环案例

[root@centos5 awk]# awk -F: '$3>=500{for (i=1;i<=NF;i+=2) print $i}' /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对文本文件进行处理。

一、什么是sed?

sed 是一种在线编辑器,它一次处理一行内容。sed是非交互式的编辑器。它不会修改文件,除非使用shell重定向来保存结果。默认情况下,所有的输出行都被打印到屏幕上。

二、sed的处理过程

sed编辑器逐行处理文件(或输入),并将结果发送到屏幕。具体过程如下:首先sed把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。sed每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed便结束运行。

前面说到sed不会修改文件,那么现在我们可以知道是为什么了?是因为sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修改原文件。

补充知识:

在使用sed的过程中,我们经常会听到“定址”,那么什么是“定址”呢?

定址用于决定对哪些行进行编辑。地址的形式可以是数字、正则表达式、或二者的结合。如果没有指定地址,sed将处理输入文件的所有行。

1、地址是一个数字,则表示行号;是“$"符号,则表示最后一行。

例如:

[plain] view plaincopy

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

2、只显示指定行范围的文件内容

例如:

[plain] view plaincopy

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

3、地址是逗号分隔的,那么需要处理的地址是这两行之间的范围(包括这两行在内)。范围可以用数字、正则表达式、或二者的组合表示。

例如:

[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"的行到第十行的内容

三、sed命令和选项

sed命令告诉sed如何处理由地址指定的各输入行,如果没有指定地址则处理所有的输入行。

1、sed命令

命令

功能

a\

在当前行后添加一行或多行。多行时除最后一行外,每行末尾需用“\”续行

c\

用此符号后的新文本替换当前行中的文本。多行时除最后一行外,每行末尾需用"\"续行

i\

在当前行之前插入文本。多行时除最后一行外,每行末尾需用"\"续行

d

删除行

h

把模式空间里的内容复制到暂存缓冲区

H

把模式空间里的内容追加到暂存缓冲区

g

把暂存缓冲区里的内容复制到模式空间,覆盖原有的内容

G

把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面

l

列出非打印字符

p

打印行

n

读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理

q

结束或退出sed

r

从文件中读取输入行

!

对所选行以外的所有行应用命令

s

用一个字符串替换另一个

g

在行内进行全局替换

w

将所选的行写入文件

x

交换暂存缓冲区与模式空间的内容

y

将字符替换为另一字符(不能对正则表达式使用y命令)

2、sed选项

选项

功能

-e

进行多项编辑,即对输入行应用多条sed命令时使用

-n

取消默认的输出

-f

指定sed脚本的文件名

四、正则表达式元字符

与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的行

五、sed的退出状态

sed不向grep一样,不管是否找到指定的模式,它的退出状态都是0。只有当命令存在语法错误时,sed的退出状态才不是0。

六、常用范例

1、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的行打印一遍。

2、d命令

命令d用于删除输入行。sed先将输入行从文件复制到模式空间里,然后对该行执行sed命令,最后将模式空间里的内容显示在屏幕上。如果发出的是命令d,当前模式空间里的输入行会被删除,不被显示。

例子:

[plain] view plaincopy

  1. (1)sed '$d' datafile
  2. #删除最后一行,其余的都被显示
  3. (2)sed '/my/d' datafile
  4. #删除包含my的行,其余的都被显示

3、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命令,就成了新的串分隔符。

4、e选项

-e是编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作将应用到模式缓冲区中的行上。

例子:

[plain] view plaincopy

  1. sed -e '1,10d' -e 's/My/Your/g' datafile
  2. #选项-e用于进行多重编辑。第一重编辑删除第1-3行。第二重编辑将出现的所有My替换为Your。因为是逐行进行这两项编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。

5、r命令

r命令是读命令。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置上。

例如:

[plain] view plaincopy

  1. sed '/My/r introduce.txt' datafile
  2. #如果在文件datafile的某一行匹配到模式My,就在该行后读入文件introduce.txt的内容。如果出现My的行不止一行,则在出现My的各行后都读入introduce.txt文件的内容。

6、w命令

例子:

[plain] view plaincopy

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

7、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

8、i\ 命令

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

9、c\ 命令

sed使用该命令将已有文本修改成新的文本。

10、n命令

sed使用该命令获取输入文件的下一行,并将其读入到模式缓冲区中,任何sed命令都将应用到匹配行紧接着的下一行上。

例如:

[plain] view plaincopy

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

注:如果需要使用多条命令,或者需要在某个地址范围内嵌套地址,就必须用花括号将命令括起来,每行只写一条命令,或这用分号分割同一行中的多条命令。

11、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命令的分隔符一样,斜线可以被替换成其它的字符。

12、q命令

q命令将导致sed程序退出,不再进行其它的处理。

[plain] view plaincopy

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

13、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

七、sed脚本编写方法

1、从文件读入命令

[plain] view plaincopy

  1. sed -f sed.sh

sed.sh文件内容:

[plain] view plaincopy

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

2、直接运行脚本 ./sed.sh /etc/passwd

[plain] view plaincopy

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

八、小技巧

1、用sed 输出自己的IP 地址

[plain] view plaincopy

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

2、在sed的命令行中引用shell变量时要使用双引号,而不是通常所用的单引号。下面是一个根据name变量的内容来删除named.conf文件中zone段的脚本:

name='zone\ "localhost"'

[plain] view plaincopy

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

3、保持和获取:h命令和G命令

[plain] view plaincopy

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

在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。

4、保持和互换:h命令和x命令

[plain] view plaincopy

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

互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。

九、练习

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

awk sed 总结的更多相关文章

  1. <转>如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等

    原文链接:http://www.vaikan.com/use-multiple-cpu-cores-with-your-linux-commands/ 你是否曾经有过要计算一个非常大的数据(几百GB) ...

  2. 转摘--如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等

    http://www.vaikan.com/use-multiple-cpu-cores-with-your-linux-commands/ 你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或 ...

  3. 如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等(转)

    你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作——一些无法并行的操作.数据专家们,我是在对你们说.你可能有一个4核或更多核的CPU,但我们合适的工具,例如 grep, ...

  4. awk\sed\grep 补充

    # awk\sed\grep 补充 以上命令中字符 / 在sed中作为定界符使用,也可以使用任意的定界符 sed's:test:TEXT:g' sed's|test|TEXT|g' 定界符出现在样式内 ...

  5. echo\awk\sed\tee\curl的使用-shell

    echo的使用:http://man.linuxde.net/echo awk的使用:http://man.linuxde.net/awk sed的使用:http://man.linuxde.net/ ...

  6. 【转】如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等

    如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等   你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作——一些无法并 ...

  7. linux的文件处理(匹配 正则表达式 egrep awk sed)和系统、核心数据备份

    文件处理 1.处理方式 匹配 正则表达式 egrep awk sed 2.文件中的处理字符 \n  新行符 换行 \t  制表符 tab键 缺省8个空格 \b  退格符 backspace键 退格键 ...

  8. 【linux系统】命令学习(六)awk sed grep 与管道的使用

    程序运行环境输入与输出 标准输入0 read a;echo $a 标准输出1 echo cesh 错误输出 ls notr 管道重定向 管道与管道之间可以重定向 管道与文件之间可以重定向 用于写入 将 ...

  9. 基本shell编程【3】- 常用的工具awk\sed\sort\uniq\od

    awk awk是个很好用的东西,大量使用在linux系统分析的结果展示处理上.并且可以使用管道, input | awk ''  | output 1.首先要知道形式 awk 'command' fi ...

随机推荐

  1. 【Java EE 学习 22 上】【文件上传】【目录打散】【文件重命名】

    1.文件上传概述 (1)使用<input type="file">的方式来声明一个文件域. (2)表单提交方式一定要是post方式才行 (3)表单属性enctype 默 ...

  2. Linux使用ssh-keygen实现SSH无密码登录

    一.原理简介: 1.SSH公钥认证的基本原理:     SSH是一个专为远程登录会话和其他网络服务提供安全性的协议.默认状态下SSH链接是需要密码认证的,可以通过添加系统认证(即公钥-私钥)的修改,修 ...

  3. x64内核内存空间结构

    0x00 前言 本文主要是讨论Windows 7 x64下的内核虚拟地址空间的结构,可以利用WiinDBG调试的扩展命令"!CMKD.kvas"来显示x64下的内核虚拟地址空间的整 ...

  4. Hibernate的抓取策略

    立即检索:当执行某行代码的时候,马上发出SQL语句进行查询(get())延迟检索:当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句(load()) 类级 ...

  5. MyBatis - MyBatis Generator 生成的example 如何使用 and or 简单混合查询

    简单介绍: Criteria,包含一个Cretiron的集合,每一个Criteria对象内包含的Cretiron之间是由AND连接的,是逻辑与的关系. oredCriteria,Example内有一个 ...

  6. JSON.parse()和JSON.stringify()区别

    parse用于从一个字符串中解析出json对象,如: var str = '{"name":"huangxiaojian","age":&q ...

  7. 服务器&浏览器伪装的故事

    今天要说的是伪装,为嘛要伪装呢?我想,首先是心虚,不够自信,比如你安全措施做的不够,你怕别人黑你的系统,所以就要伪装.其次呢,我想就是有不可告人的秘密了,比如你有竞争对手总是找你的茬,拦截你,那咋办呢 ...

  8. [poj2337]求字典序最小欧拉回路

    注意:找出一条欧拉回路,与判定这个图能不能一笔联通...是不同的概念 c++奇怪的编译规则...生不如死啊... string怎么用啊...cincout来救? 可以直接.length()我也是长见识 ...

  9. Listener refused the connection with the following error 错误解决

    原文地址 :http://blog.csdn.net/zajin/article/details/17753351 做个备份: 查询数据库当前进程的连接数: select count(*) from ...

  10. NOIP2014 uoj20解方程 数论(同余)

    又是数论题 Q&A Q:你TM做数论上瘾了吗 A:没办法我数论太差了,得多练(shui)啊 题意 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, ...