awk 练习题-02

发布于 2018-01-30  378 次阅读


awk 中使用外部 shell 变量

如:
A=44 echo "ABCD" | awk -v GET_A=$A ’{print GET_A}’
说明:-v 选项用于定义参数,这里表示将变量 A 的值赋予 GET_A。
有多少个变量需要赋值,就需要多少个-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
附件:
cat filename
1111111:13443253456
2222222:13211222122
1111111:13643543544
3333333:12341243123
2222222:12123123123
运行脚本后结果为:
[1111111]
13443253456
13643543544
[2222222]
13211222122
12123123123
[3333333]
12341243123

awk 合并一个文件

我有这样的需求,需要把两个文件中,第一列相同的行合并到同一行中。举个例子,有两个文件,内容如下
cat 1.txt
1 aa
2 bb
3 ee
4 ss
cat 2.txt
1 ab
2 cd
3 ad
4 bd
5 de
合并后的结果为:
1 ab aa
2 cd bb
3 ad ee
4 bd ss
5 de
实现的命令为:
awk 'NR==FNR{a[$1]=$2}NR>FNR{print $0,a[$1]}'  1.txt  2.txt
解释:NR 表示读取的行数,FNR 表示读取的当前行数
所以其实 NR==FNR 就表示读取 2.txt 的时候。 同理 NR>FNR 表示读取 1.txt 的时候
数组 a 其实就相当于一个 map

把一个文件多行连接成一行

第 1 句命令:a=`cat file`;echo $a
[root@am-01:/tmp#] a=`cat 1.txt`;echo $a
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 111 333 123 321 sad qdg aaa # % ^
第 2 句命令:awk '{printf("%s ",$0)}' file   // %s 后记得要有一空格,否则出来就是完全连在一起的,中间连空格都没有
[root@am-01:/tmp#] awk '{printf("%s ",$0)}' 1.txt
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 111 333 123 321 sad qdg aaa # % ^
第 3 句命令:cat file | xargs
[root@am-01:/tmp#] cat 1.txt | xargs
root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin 111 333 123 321 sad qdg aaa # % ^

awk 中 gsub 函数的使用

awk 'gsub(/root/,"abc")' /tmp/1.txt  // passwd 文件中把所有 root 替换为 abc
awk -F ':' 'gsub(/root/,"abc",$1) {print $0}' /tmp/1.txt  // 替换$1 中的 root 为 abc
[root@am-01:/tmp#] cp /etc/passwd /tmp/1.txt
[root@am-01:/tmp#] awk 'gsub(/root/,"abc")' /tmp/1.txt
abc:x:0:0:abc:/abc:/bin/bash
operator:x:11:0:operator:/abc:/sbin/nologin
[root@am-01:/tmp#] awk -F ':' 'gsub(/root/,"abc",$1) {print $0}' /tmp/1.txt
abc x 0 0 root /root /bin/bash

awk 截取指定多个域为一行

for j in `seq 0 20`; do
        let x=100*$j
        let y=$x+1
        let z=$x+100
        for i in `seq $y $z` ; do
                awk  -v a=$i '{printf $a " "}' example.txt >>/tmp/test.txt
                echo " " >>/tmp/test.txt
        done
done

过滤两个或多个关键词

grep -E 'root|user' filename  // 找出文件(filename)中包含 root 或者包含 user 的行
[root@am-01:/tmp#] grep -E 'root|user' 1.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1003:1005::/home/user3:/bin/bash
user4:x:1004:1005::/home/aming111:/sbin/nologin
user5:x:1005:1006::/home/user5:/bin/bash
user6:x:1007:1007::/home/user6:/bin/bash
egrep 'root|user' filename    //用 egrep 同样可以实现
[root@am-01:/tmp#] egrep 'root|user' 1.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1003:1005::/home/user3:/bin/bash
user4:x:1004:1005::/home/aming111:/sbin/nologin
user5:x:1005:1006::/home/user5:/bin/bash
user6:x:1007:1007::/home/user6:/bin/bash
awk '/root|user/'  filename // awk 的实现方式
[root@am-01:/tmp#] awk '/root|user/' 1.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
user1:x:1001:1001::/home/user1:/bin/bash
user2:x:1002:1002::/home/user2:/bin/bash
user3:x:1003:1005::/home/user3:/bin/bash
user4:x:1004:1005::/home/aming111:/sbin/nologin
user5:x:1005:1006::/home/user5:/bin/bash
user6:x:1007:1007::/home/user6:/bin/bash

合并两个文件

[root@am-01:/tmp#] cat 2.txt
115
231
525
231
115
1
1
2
[root@am-01:/tmp#] cat 3.txt
2 1
2 115
1 2
2 231
1 525
2 1
2 115
1 2
2 231
1 525
[root@am-01:/tmp#] paste 2.txt 3.txt
115 2 1
231 2 115
525 1 2
231 2 231
115 1 525
1 2 1
1 2 115
2 1 2
2 231
1 525
[root@am-01:/tmp#] paste -d '+' 2.txt 3.txt
115+2 1
231+2 115
525+1 2
231+2 231
115+1 525
1+2 1
1+2 115
2+1 2
+2 231
+1 525