awk sed 总结
Awk总结笔记
介绍
90年代 new awk :nawk
Linux 的是gawk 我们简化awk
用法
# awk [options ] ‘scripts’ file1 file2 ....
# awk [options ] ‘PATTERN {action }’ file1 file2 ....
读入文本先切片如下 切5片
每片$n 整行$0
每行片数不一样
内置变量
以下为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
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的模式
正则表达式 模式+动作
变量,先在变量外加双引号,再加单引号即可,如:
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
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
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
- sed -n '3p' datafile #只打印第三行
2、只显示指定行范围的文件内容
例如:
[plain] view plaincopy
- sed -n '100,200p' mysql_slow_query.log # 只查看文件的第100行到第200行
3、地址是逗号分隔的,那么需要处理的地址是这两行之间的范围(包括这两行在内)。范围可以用数字、正则表达式、或二者的组合表示。
例如:
[plain] view plaincopy
- sed '2,5d' datafile
- #删除第二到第五行
- sed '/My/,/You/d' datafile
- #删除包含"My"的行到包含"You"的行之间的行
- sed '/My/,10d' datafile
- #删除包含"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
- 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)sed '/my/p' datafile
- #默认情况下,sed把所有输入行都打印在标准输出上。如果某行匹配模式my,p命令将把该行另外打印一遍。
- (2)sed -n '/my/p' datafile
- #选项-n取消sed默认的打印,p命令把匹配模式my的行打印一遍。
2、d命令
命令d用于删除输入行。sed先将输入行从文件复制到模式空间里,然后对该行执行sed命令,最后将模式空间里的内容显示在屏幕上。如果发出的是命令d,当前模式空间里的输入行会被删除,不被显示。
例子:
[plain] view plaincopy
- (1)sed '$d' datafile
- #删除最后一行,其余的都被显示
- (2)sed '/my/d' datafile
- #删除包含my的行,其余的都被显示
3、s命令
例子:
[plain] view plaincopy
- (1)sed 's/^My/You/g' datafile
- #命令末端的g表示在行内进行全局替换,也就是说如果某行出现多个My,所有的My都被替换为You。
- (2)sed -n '1,20s/My$/You/gp' datafile
- #取消默认输出,处理1到20行里匹配以My结尾的行,把行内所有的My替换为You,并打印到屏幕上。
- (3)sed 's#My#Your#g' datafile
- #紧跟在s命令后的字符就是查找串和替换串之间的分隔符。分隔符默认为正斜杠,但可以改变。无论什么字符(换行符、反斜线除外),只要紧跟s命令,就成了新的串分隔符。
4、e选项
-e是编辑命令,用于sed执行多个编辑任务的情况下。在下一行开始编辑前,所有的编辑动作将应用到模式缓冲区中的行上。
例子:
[plain] view plaincopy
- sed -e '1,10d' -e 's/My/Your/g' datafile
- #选项-e用于进行多重编辑。第一重编辑删除第1-3行。第二重编辑将出现的所有My替换为Your。因为是逐行进行这两项编辑(即这两个命令都在模式空间的当前行上执行),所以编辑命令的顺序会影响结果。
5、r命令
r命令是读命令。sed使用该命令将一个文本文件中的内容加到当前文件的特定位置上。
例如:
[plain] view plaincopy
- sed '/My/r introduce.txt' datafile
- #如果在文件datafile的某一行匹配到模式My,就在该行后读入文件introduce.txt的内容。如果出现My的行不止一行,则在出现My的各行后都读入introduce.txt文件的内容。
6、w命令
例子:
[plain] view plaincopy
- sed -n '/hrwang/w me.txt' datafile
7、a\ 命令
a\ 命令是追加命令,追加将添加新文本到文件中当前行(即读入模式缓冲区中的行)的后面。所追加的文本行位于sed命令的下方另起一行。如果要追加的内容超过一行,则每一行都必须以反斜线结束,最后一行除外。最后一行将以引号和文件名结束。
例子:
[plain] view plaincopy
- sed '/^hrwang/a\
- >hrwang and mjfan are husband\
- >and wife' datafile
- #如果在datafile文件中发现匹配以hrwang开头的行,则在该行下面追加hrwang and mjfan are husband and wife
8、i\ 命令
i\ 命令是在当前行的前面插入新的文本。
9、c\ 命令
sed使用该命令将已有文本修改成新的文本。
10、n命令
sed使用该命令获取输入文件的下一行,并将其读入到模式缓冲区中,任何sed命令都将应用到匹配行紧接着的下一行上。
例如:
[plain] view plaincopy
- sed '/hrwang/{n;s/My/Your/;}' datafile
注:如果需要使用多条命令,或者需要在某个地址范围内嵌套地址,就必须用花括号将命令括起来,每行只写一条命令,或这用分号分割同一行中的多条命令。
11、y命令
该命令与UNIX/Linux中的tr命令类似,字符按照一对一的方式从左到右进行转换。例如,y/abc/ABC/将把所有小写的a转换成A,小写的b转换成B,小写的c转换成C。
例如:
[plain] view plaincopy
- sed '1,20y/hrwang12/HRWANG^$/' datafile
- #将1到20行内,所有的小写hrwang转换成大写,将1转换成^,将2转换成$。
- #正则表达式元字符对y命令不起作用。与s命令的分隔符一样,斜线可以被替换成其它的字符。
12、q命令
q命令将导致sed程序退出,不再进行其它的处理。
[plain] view plaincopy
- sed '/hrwang/{s/hrwang/HRWANG/;q;}' datafile
13、h命令和g命令
为了更好说明这两个命令,我们先创建如下的文本文件:
[plain] view plaincopy
- #cat datafile
- My name is hrwang.
- Your name is mjfan.
- hrwang is mjfan's husband.
- mjfan is hrwang's wife.
[plain] view plaincopy
- sed -e '/hrwang/h' -e '$G' datafile
- sed -e '/hrwang/H' -e '$G' datafile
- #通过上面两条命令,你会发现h会把原来暂存缓冲区的内容清除,只保存最近一次执行h时保存进去的模式空间的内容。而H命令则把每次匹配hrwnag的行都追加保存在暂存缓冲区。
- sed -e '/hrwang/H' -e '$g' datafile
- sed -e '/hrwang/H' -e '$G' datafile
- #通过上面两条命令,你会发现g把暂存缓冲区中的内容替换掉了模式空间中当前行的内容,此处即替换了最后一行。而G命令则把暂存缓冲区的内容追加到了模式空间的当前行后。此处即追加到了末尾。
补充知识点:sed特殊用法
[plain] view plaincopy
- sed -n '/root/w a.txt' #将匹配行输出到文件
- sed '/root/r abc.txt' /etc/passwd #把abc.txt的文件内容读入到root匹配行后
- sed -n '/root/w a.txt'
- sed -n '/root/{=;p}' /etc/passwd #打印行号和匹配root的行
- sed -n '/root/{n;d}' /etc/passwd #将匹配root行的下一行删除
- sed -n '/root/{N;d}' /etc/passwd #将匹配root行和下一行都删除
- sed '22{h;d};23,33{H;d};44G' pass
七、sed脚本编写方法
1、从文件读入命令
[plain] view plaincopy
- sed -f sed.sh
sed.sh文件内容:
[plain] view plaincopy
- s/root/yerik/p
- s/bash/csh/p
2、直接运行脚本 ./sed.sh /etc/passwd
[plain] view plaincopy
- #!/bib/sed -f
- s/root/yerik/p
- s/bash/csh/p
八、小技巧
1、用sed 输出自己的IP 地址
[plain] view plaincopy
- 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
- sed "/$name/,/};/d" named.conf
3、保持和获取:h命令和G命令
[plain] view plaincopy
- $ sed -e '/test/h' -e '$G example
在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。
4、保持和互换:h命令和x命令
[plain] view plaincopy
- $ sed -e '/test/h' -e '/check/x' example
互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。
九、练习
1,删除文件每行的第一个字符。
[plain] view plaincopy
- sed -n 's/^.//gp' /etc/passwd
- sed -nr 's/(.)(.*)/\2/p' /etc/passwd
2,删除文件每行的第二个字符。
[plain] view plaincopy
- sed -nr 's/(.)(.)(.*)/\1\3/p' /etc/passwd
3,删除文件每行的最后一个字符。
[plain] view plaincopy
- sed -nr 's/.$//p' /etc/passwd
- sed -nr 's/(.*)(.)/\1/p' /etc/passwd
4,删除文件每行的倒数第二个字符。
[plain] view plaincopy
- sed -nr 's/(.*)(.)(.)/\1\3/p' /etc/passwd
5,删除文件每行的第二个单词。
[plain] view plaincopy
- sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\2\3\5/p' /etc/passwd
6,删除文件每行的倒数第二个单词。
[plain] view plaincopy
- 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
- sed -nr 's/(.*)([^a-Z]+)([a-Z]+)([^a-Z]*)/\1\2\4/p' /etc/samba/smb.conf
8,交换每行的第一个字符和第二个字符。
[plain] view plaincopy
- sed -nr 's/(.)(.)(.*)/\2\1\3/p' /etc/passwd
9,交换每行的第一个单词和第二个单词。
[plain] view plaincopy
- 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
- sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)([a-Z]+)(.*)/\1\4\3\2\5/p' /etc/passwd
11,删除一个文件中所有的数字。
[plain] view plaincopy
- sed 's/[0-9]*//g' /etc/passwd
12,删除每行开头的所有空格。
[plain] view plaincopy
- sed -n 's/^\ *//p' /etc/samba/smb.conf
- sed -nr 's/( *)(.*)/\2/p' testp
13,用制表符替换文件中出现的所有空格。
[plain] view plaincopy
- sed -n 's/\ /\t/gp' pass
14,把所有大写字母用括号()括起来。
[plain] view plaincopy
- sed -nr 's/([A-Z])/(&)/gp' testp
- sed -n 's/[A-Z]/(&)/gp' testp
15,打印每行3次。
[plain] view plaincopy
- sed 'p;p' pass
16,隔行删除。
[plain] view plaincopy
- sed -n '1~2p' pass
17,把文件从第22行到第33行复制到第44行后面。
[plain] view plaincopy
- sed '1,21h;22h;23,33H;44G' pass
18,把文件从第22行到第33行移动到第44行后面。
[plain] view plaincopy
- sed '22{h;d};23,33{H;d};44G' pass
19,只显示每行的第一个单词。
[plain] view plaincopy
- sed -nr 's/([^a-Z]*)([a-Z]+)([^a-Z]+)(.*)/\2/p' /etc/passwd
20,打印每行的第一个单词和第三个单词。
[plain] view plaincopy
- 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
- date +%m/%Y/%d |sed -n 's#/#;#gp'
22, 逆向输出
[plain] view plaincopy
- cat a.txt
- ABC
- DEF
- XYZ
- 输出样式变成
- XYZ
- DEF
- ABC
awk sed 总结的更多相关文章
- <转>如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等
原文链接:http://www.vaikan.com/use-multiple-cpu-cores-with-your-linux-commands/ 你是否曾经有过要计算一个非常大的数据(几百GB) ...
- 转摘--如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等
http://www.vaikan.com/use-multiple-cpu-cores-with-your-linux-commands/ 你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或 ...
- 如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等(转)
你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作——一些无法并行的操作.数据专家们,我是在对你们说.你可能有一个4核或更多核的CPU,但我们合适的工具,例如 grep, ...
- awk\sed\grep 补充
# awk\sed\grep 补充 以上命令中字符 / 在sed中作为定界符使用,也可以使用任意的定界符 sed's:test:TEXT:g' sed's|test|TEXT|g' 定界符出现在样式内 ...
- echo\awk\sed\tee\curl的使用-shell
echo的使用:http://man.linuxde.net/echo awk的使用:http://man.linuxde.net/awk sed的使用:http://man.linuxde.net/ ...
- 【转】如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等
如何利用多核CPU来加速你的Linux命令 — awk, sed, bzip2, grep, wc等 你是否曾经有过要计算一个非常大的数据(几百GB)的需求?或在里面搜索,或其它操作——一些无法并 ...
- linux的文件处理(匹配 正则表达式 egrep awk sed)和系统、核心数据备份
文件处理 1.处理方式 匹配 正则表达式 egrep awk sed 2.文件中的处理字符 \n 新行符 换行 \t 制表符 tab键 缺省8个空格 \b 退格符 backspace键 退格键 ...
- 【linux系统】命令学习(六)awk sed grep 与管道的使用
程序运行环境输入与输出 标准输入0 read a;echo $a 标准输出1 echo cesh 错误输出 ls notr 管道重定向 管道与管道之间可以重定向 管道与文件之间可以重定向 用于写入 将 ...
- 基本shell编程【3】- 常用的工具awk\sed\sort\uniq\od
awk awk是个很好用的东西,大量使用在linux系统分析的结果展示处理上.并且可以使用管道, input | awk '' | output 1.首先要知道形式 awk 'command' fi ...
随机推荐
- 【Java EE 学习 22 上】【文件上传】【目录打散】【文件重命名】
1.文件上传概述 (1)使用<input type="file">的方式来声明一个文件域. (2)表单提交方式一定要是post方式才行 (3)表单属性enctype 默 ...
- Linux使用ssh-keygen实现SSH无密码登录
一.原理简介: 1.SSH公钥认证的基本原理: SSH是一个专为远程登录会话和其他网络服务提供安全性的协议.默认状态下SSH链接是需要密码认证的,可以通过添加系统认证(即公钥-私钥)的修改,修 ...
- x64内核内存空间结构
0x00 前言 本文主要是讨论Windows 7 x64下的内核虚拟地址空间的结构,可以利用WiinDBG调试的扩展命令"!CMKD.kvas"来显示x64下的内核虚拟地址空间的整 ...
- Hibernate的抓取策略
立即检索:当执行某行代码的时候,马上发出SQL语句进行查询(get())延迟检索:当执行某行代码的时候,不会马上发出SQL语句进行查询.当真正使用这个对象的时候才会发送SQL语句(load()) 类级 ...
- MyBatis - MyBatis Generator 生成的example 如何使用 and or 简单混合查询
简单介绍: Criteria,包含一个Cretiron的集合,每一个Criteria对象内包含的Cretiron之间是由AND连接的,是逻辑与的关系. oredCriteria,Example内有一个 ...
- JSON.parse()和JSON.stringify()区别
parse用于从一个字符串中解析出json对象,如: var str = '{"name":"huangxiaojian","age":&q ...
- 服务器&浏览器伪装的故事
今天要说的是伪装,为嘛要伪装呢?我想,首先是心虚,不够自信,比如你安全措施做的不够,你怕别人黑你的系统,所以就要伪装.其次呢,我想就是有不可告人的秘密了,比如你有竞争对手总是找你的茬,拦截你,那咋办呢 ...
- [poj2337]求字典序最小欧拉回路
注意:找出一条欧拉回路,与判定这个图能不能一笔联通...是不同的概念 c++奇怪的编译规则...生不如死啊... string怎么用啊...cincout来救? 可以直接.length()我也是长见识 ...
- Listener refused the connection with the following error 错误解决
原文地址 :http://blog.csdn.net/zajin/article/details/17753351 做个备份: 查询数据库当前进程的连接数: select count(*) from ...
- NOIP2014 uoj20解方程 数论(同余)
又是数论题 Q&A Q:你TM做数论上瘾了吗 A:没办法我数论太差了,得多练(shui)啊 题意 题目描述 已知多项式方程: a0+a1x+a2x^2+..+anx^n=0 求这个方程在[1, ...