linux学习lesson30
程序员文章站
2022-05-31 16:17:50
...
目录
1 复习2
2.1 awk 中使用外部shell变量
- 如:A=44; echo "ABCD" | awk -v GET_A=$A ’{print GET_A}’
说明:-v选项用于定义参数,这里表示将变量A的值赋予GET_A。
- 有多少个变量需要赋值,就需要多少个-v选项。与之等价的:应用于脚本中:
[[email protected] dir9]# vim awk_variable.sh
#!/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 #方法1
#awk -F ':' ' $1=='$id' {print $2}' filename #方法2
done
- 附件:
[[email protected] dir9]# cat filename
1111111:13443253456
2222222:13211222122
1111111:13643543544
3333333:12341243123
2222222:12123123123
- 运行脚本后结果:
[[email protected] dir9]# sh awk_variable.sh
[1111111]
13443253456
13643543544
[2222222]
13211222122
12123123123
[3333333]
12341243123
2.2 awk 合并一个文件
- 有这样的需求,需要把两个文件中,第一列相同的行合并到同一行中。举个例子,有两个文件,内容如下
[[email protected] dir9]# cat 1.txt
1 aa
2 bb
3 ee
4 ss
[[email protected] dir9]# cat 2.txt
1 ab
2 cd
3 ad
4 bd
5 de
- 合并后的结果为:
[[email protected] dir9]# awk 'NR==FNR {a[$1]=$2} NR>FNR {print $0,a[$1]}' 1.txt 2.txt
1 ab aa
2 cd bb
3 ad ee
4 bd ss
5 de
解释:NR表示读取的行数, FNR表示读取的当前行数,大家可以运行这个命令 awk '{print NR,FNR}' 1.txt 2.txt,比较NR和FNR
所以其实NR==FNR 就表示读取1.txt的时候。 同理NR>FNR表示读取2.txt的时候
数组a其实就相当于一个map
2.3 把一个文件多行连接成一行
a=`cat file`;echo $a
awk '{printf("%s ",$0)}' file // %s 后记得要有一空格,否则出来就是完全连在一起的,中间连空格都没有
cat file |xargs
- 应用举例:一个文件每行都有一个数字,现在需要把每行的数字用“+”连接起来
[[email protected] dir9]# cat file
96
1093
1855
1253
1364
1332
2308
2589
2531
1239
2164
2826
2787
2145
2617
4311
1810
2115
1235
[[email protected] dir9]# awk '{printf("%s+",$0)}' file;echo""
96+1093+1855+1253+1364+1332+2308+2589+2531+1239+2164+2826+2787+2145+2617+4311+1810+2115+1235+
[[email protected] dir9]# cat file|xargs|sed 's/ /+/g'
96+1093+1855+1253+1364+1332+2308+2589+2531+1239+2164+2826+2787+2145+2617+4311+1810+2115+1235
2.4 awk中gsub函数的使用
- awk 'gsub(/www/,"abc")' /etc/passwd // passwd文件中把所有www替换为abc
[[email protected] dir9]# awk 'gsub(/root/,"abc")' /etc/passwd
ROOT:x:0:0:roooot:/abc:/bin/bash
operator:x:11:0:operator:/abc:/sbin/nologin
- awk -F ':' 'gsub(/www/,"abc",$1) {print $0}' /etc/passwd // 替换$1中的www为abc
[[email protected] dir9]# awk -F ':' 'gsub(/adm/,"abc",$1)' /etc/passwd
abc x 3 4 adm /var/adm /sbin/nologin
- awk 'sub(/www/,"abc")' /etc/passwd // passwd文件中把第一次出现的www替换为abc
[[email protected] dir9]# awk 'gsub(/adm/,"abc")' testpasswd
abc:x:3:4:abc:/var/abc:/sbin/nologin
[[email protected] dir9]# awk 'sub(/adm/,"abc")' testpasswd
abc:x:3:4:adm:/var/adm:/sbin/nologin
2.5 awk 截取指定多个域为一行
- 用awk指定分隔符把文本分为若干段。如何把相同段的内容弄到一行?
- 以/etc/passwd为例,该文件以":"作为分隔符,分为了7段。
[[email protected] dir9]# sh awk_part.sh
#!/bin/bash
for i in `seq 1 7`
do
awk -F ':' -v a=$i '{printf $a " "}' /etc/passwd
echo
done
- 过滤两个或多个关键词
- grep -E '123|abc' filename // 找出文件(filename)中包含123或者包含abc的行
[[email protected] dir9]# grep -E 'adm|root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
- egrep '123|abc' filename //用egrep同样可以实现
[[email protected] dir9]# egrep 'adm|root' /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
- awk '/123|abc/' filename // awk 的实现方式
[[email protected] dir9]# awk '/adm|root/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
adm:x:3:4:adm:/var/adm:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
2.6 用awk生成以下结构文件
- 用awk编写生成以下结构文件的程序。( 最后列使用现在的时间,时间格式为YYYYMMDDHHMISS) 各列的值应如下所示,每增加一行便加1,共500万行。
- 1,1,0000000001,0000000001,0000000001,0000000001,0000000001,0000000001,2005100110101
- 2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,2005100110101
[[email protected] dir9]# awk 'BEGIN{for(i=1;i<=10;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,20181021233750
2,2,0000000002,0000000002,0000000002,0000000002,0000000002,0000000002,20181021233750
3,3,0000000003,0000000003,0000000003,0000000003,0000000003,0000000003,20181021233750
4,4,0000000004,0000000004,0000000004,0000000004,0000000004,0000000004,20181021233750
5,5,0000000005,0000000005,0000000005,0000000005,0000000005,0000000005,20181021233750
6,6,0000000006,0000000006,0000000006,0000000006,0000000006,0000000006,20181021233750
7,7,0000000007,0000000007,0000000007,0000000007,0000000007,0000000007,20181021233750
8,8,0000000008,0000000008,0000000008,0000000008,0000000008,0000000008,20181021233750
9,9,0000000009,0000000009,0000000009,0000000009,0000000009,0000000009,20181021233750
10,10,0000000010,0000000010,0000000010,0000000010,0000000010,0000000010,20181021233750
2.7 awk用print打印单引号
awk 'BEGIN{print "a'"'"'s"}' //不用脱义,就多写几个单引号、双引号
awk 'BEGIN{print "a'\''s"}' //用脱义,脱义的是单引号
awk 'BEGIN{print "a\"s"}' //用脱义,脱义的是双引号
2.8 合并两个文件
- paste filename1 filename2
[[email protected] dir9]# cat 1.txt
1 aa
2 bb
3 ee
4 ss
[[email protected] dir9]# cat 2.txt
1 ab
2 cd
3 ad
4 bd
5 de
- 则paste 1.txt 2.txt结果为:
[[email protected] dir9]# paste 1.txt 2.txt
1 aa 1 ab
2 bb 2 cd
3 ee 3 ad
4 ss 4 bd
5 de
- 如果,你想在两个文件连接处用一个指定的字符连接,还可以用-d来指定
- paste -d '+' a.txt b.txt
- 结果为
[[email protected] dir9]# paste -d '+' 1.txt 2.txt
1 aa+1 ab
2 bb+2 cd
3 ee+3 ad
4 ss+4 bd
+5 de