复习
-
awk 中使用外部shell变量
awk的-v选项用于定义参数,有多少个变量需要赋值,就需要多少个-v选项。
脚本命令如下:
#! /bin/bash
sort -n filename |awk -F ':' '{print $1}'|uniq >id.txt
for id in `cat id.txt`; do
echo "[$id]"
awk -v id2=$id -F ':' '$1==id2 {print $2}' filename // 另外的方式为: awk -F ':' '$1=="'id'" {print $2}' filename
done
运行脚本后显示如下:
[root@minglinux-01 sbin]# cat filename
1:aaaaaaaa
2:bbbbbbbbbb
3:cccccc
1:qqqqqqq
2:rrrrrrrr
[root@minglinux-01 sbin]# sh test.sh
[1]
aaaaaaaa
qqqqqqq
[2]
bbbbbbbbbb
rrrrrrrr
[3]
cccccc
-
awk 合并一个文件
[root@minglinux-01 ~]# cat 1.txt
1 a
2 b
3 c
4 d
[root@minglinux-01 ~]# cat 2.txt
1 A
2 B
3 C
4 D
5 E
[root@minglinux-01 ~]# cat 1.txt 2.txt
1 a
2 b
3 c
4 d
1 A
2 B
3 C
4 D
5 E
[root@minglinux-01 ~]# awk '{print NR}' 1.txt 2.txt
1
2
3
4
5
6
7
8
9
[root@minglinux-01 ~]# awk '{print FNR}' 1.txt 2.txt
1
2
3
4
1
2
3
4
5
[root@minglinux-01 ~]# awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}' 1.txt 2.txt
1 A a
2 B b
3 C c
4 D d
5 E
上例中NR表示读取的行数, FNR表示读取的当前行数,通过运行awk '{print NR,FNR}' 1.txt 2.txt的结果可以看出。所以NR==FNR 就表示读取1.txt的时候,而 NR>FNR表示读取2.txt的时候。
-
把一个文件多行连接成一行
3种方法示例命令如下:
[root@minglinux-01 ~]# cat 3.txt
a
b
c
d
e
f
[root@minglinux-01 ~]# a=`cat 3.txt`;echo $a
a b c d e f
[root@minglinux-01 ~]# awk '{printf("%s ",$0)}' 3.txt;echo "" \\%s指定字符串的输出内容格式,echo "" 的作用是换行。
a b c d e f
[root@minglinux-01 ~]# cat 3.txt |xargs
a b c d e f
把3.txt中每行的字母用“+”连接起来:
[root@minglinux-01 ~]# cat 3.txt |xargs|sed 's/ /+/g'
a+b+c+d+e+f
[root@minglinux-01 ~]# awk '{printf("%s+",$0)}' 3.txt;echo""
a+b+c+d+e+f+
-
awk中gsub函数的使用
awk 'gsub(/www/,"abc")' /etc/passwd // passwd文件中把所有root替换为abc
awk -F ':' 'gsub(/www/,"abc",$1) {print $0}' /etc/passwd // 替换$1中的root为abc
[root@minglinux-01 ~]# awk 'gsub(/root/,"abc")' /etc/passwd
abc:x:0:0:abc:/abc:/bin/bash
operator:x:11:0:operator:/abc:/sbin/nologin
[root@minglinux-01 ~]# awk -F ':' 'gsub(/root/,"abc",$1) {print $0}' /etc/passwd
abc x 0 0 root /root /bin/bash
-
awk 截取指定多个域为一行
[root@minglinux-01 ~]# cat test.sh
#!/bin/bash
for i in `seq 1 7`
do
awk -F ':' -v a=$i '{printf $a " "}' /etc/passwd
echo
done
sh test.sh
root bin daemon adm lp sync shutdown halt mail operator games ftp nobody systemd-network dbus polkitd sshd postfix ming test10 user11 ntp
x x x x x x x x x x x x x x x x x x x x x x
0 1 2 3 4 5 6 7 8 11 12 14 99 192 81 999 74 89 1001 1010 1005 38
0 1 2 4 7 0 0 0 12 0 100 50 99 192 81 998 74 89 1002 1003 1004 38
root bin daemon adm lp sync shutdown halt mail operator games FTP User Nobody systemd Network Management System message bus User for polkitd Privilege-separated SSH
/root /bin /sbin /var/adm /var/spool/lpd /sbin /sbin /sbin /var/spool/mail /root /usr/games /var/ftp / / / / /var/empty/sshd /var/spool/postfix /home/ming /home/test10 /home/user11 /etc/ntp
/bin/bash /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /bin/sync /sbin/shutdown /sbin/halt /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /sbin/nologin /bin/bash /bin/bash /bin/bash /sbin/nologin
-
过滤两个或多个关键词
[root@minglinux-01 ~]# cat b.txt
letme
karsa
xiaohu
uzi
ming
.....
mlxg
uzi
lose
s8
[root@minglinux-01 ~]# grep -E 'uzi|ming' b.txt
uzi
ming
uzi
[root@minglinux-01 ~]# egrep 'uzi|ming' b.txt
uzi
ming
uzi
[root@minglinux-01 ~]# awk '/uzi|ming/' b.txt
uzi
ming
uzi
-
用awk生成以下结构文件
用awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMMSS) 各列的值应如下所示,每增加一行便加1,共500万行。
1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,2005100110101
2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,2005100110101
[root@minglinux-01 ~]# awk 'BEGIN{for(i=1;i<=5000000;i++)printf("%d,%d,%010d,%010d,%010d,%010d,%010d,%010d,%d\n",i,i,i,i,i,i,i,i,strftime("%Y%m%d%H%M%S"))}'
1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,20181022230158
2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,20181022230158
3,3,0000000003,0000000003,0000000003,0000000003,0000000003,0000000003,20181022230158
4,4,0000000004,0000000004,0000000004,0000000004,0000000004,0000000004,20181022230158
5,5,0000000005,0000000005,0000000005,0000000005,0000000005,0000000005,20181022230158
6,6,0000000006,0000000006,0000000006,0000000006,0000000006,0000000006,20181022230158
7,7,0000000007,0000000007,0000000007,0000000007,0000000007,0000000007,20181022230158
8,8,0000000008,0000000008,0000000008,0000000008,0000000008,0000000008,20181022230158
9,9,0000000009,0000000009,0000000009,0000000009,0000000009,0000000009,20181022230158
10,10,0000000010,0000000010,0000000010,0000000010,0000000010,0000000010,20181022230158
......
-
awk用print打印单引号
awk 'BEGIN{print "a'"'"'s"}' //不用脱义,就多写几个单引号、双引号
awk 'BEGIN{print "a'''s"}' //用脱义,脱义的是单引号
awk 'BEGIN{print "a"s"}' //用脱义,脱义的是双引号
[root@minglinux-01 ~]# awk 'BEGIN{print "a'"'"'s"}'
a's
[root@minglinux-01 ~]# awk 'BEGIN{print "a'\''s"}'
a's
[root@minglinux-01 ~]# awk 'BEGIN{print "a\"s"}'
a"s
-
把两个文件中相同的行合并成一行
[root@minglinux-01 ~]# cat 1.txt
a b c
1 2 3
4 5 6
[root@minglinux-01 ~]# cat 2.txt
c b a
3 2 1
6 5 4
[root@minglinux-01 ~]# paste 1.txt 2.txt
a b c c b a
1 2 3 3 2 1
4 5 6 6 5 4
还可以用-d选项在两个文件连接处用一个指定的字符连接,示例命令如下:
[root@minglinux-01 ~]# paste -d '+' 1.txt 2.txt
a b c+c b a
1 2 3+3 2 1
4 5 6+6 5 4