Linux三剑客:awk的实用案例

目录

实战案例

1、awk插入几个新字段

2、awk格式化空白

3、awk筛选IPv4地址

4、awk读取.ini配置文件中的某段

5 、使用awk根据某字段去重

6、awk次数统计

7、awk统计TCP连接状态数量

8、awk统计日志中各IP访问非200状态码的次数

9、awk统计独立IP

10、awk处理字段缺失的数据

11、awk处理字段中包含了字段分隔符的数据

12、awk取字段中指定字符数量

13、awk行列转换

14、awk行列转换2

15、awk筛选给定时间范围内的日志

16、awk去掉/**/中间的注释

17、awk前后段落关系判断

18、awk两个文件的处理

19、统计多项数据

20、处理段落

总结


实战案例

1、awk插入几个新字段

在”a b c d”的b后面插入3个字段e f g

[root@centos111 test]# echo a b c d|awk '{$3="e f g "$3}1'
a b e f g c d

2、awk格式化空白

移除每行的前缀、后缀空白,并将各部分左对齐。

文本内容:

PLAINTEXTaaaa        bbb     ccc                 bbb     aaa ccc
ddd       fff             eee gg hh ii jj

awk实现:

awk 'BEGIN{OFS="\t"}{$1=$1;print}' test.txt 
PLAINTEXT
aaaa	bbb	ccc
bbb	aaa	ccc
ddd	fff	eee	gg	hh	ii	jj

3、awk筛选IPv4地址

从ifconfig命令的结果中筛选出除了lo网卡外的所有IPv4地址。

方法1:

[root@centos111 test]# ifconfig | awk '/inet / && !($2 ~ /^127/){print $2}'
192.168.159.200

方法2:

[root@centos111 test]# ifconfig | awk 'BEGIN{RS=""}!/lo/{print $6}'
192.168.159.200
//这里是利用指定输入时的换行符为空格,然后取到了第六个字符,这个字符就是我们需要的ip

方法3:

[root@centos111 test]# ifconfig | awk 'BEGIN{RS="";FS="\n"}!/lo/{$0=$2;FS=" ";$0=$0;print $2}' 
192.168.159.200

4、awk读取.ini配置文件中的某段

文本内容:

[base]
name=os_repo
baseurl=https://xxx/centos/$releasever/os/$basearch
gpgcheck=0
​
enable=1
​
[mysql]
name=mysql_repo
baseurl=https://xxx/mysql-repo/yum/mysql-5.7-community/el/$releasever/$basearch
​
gpgcheck=0
enable=1
​
[epel]
name=epel_repo
baseurl=https://xxx/epel/$releasever/$basearch
gpgcheck=0
enable=1
[percona]
name=percona_repo
baseurl = https://xxx/percona/release/$releasever/RPMS/$basearch
enabled = 1
gpgcheck = 0

awk实现:

script.sh:

BEGIN{RS=""}
/\[mysql\]/{print;while( (getline)>0 ){if(/\[.*\]/){exit}print}}
[root@centos111 test]# awk -f script.sh test.txt 
[mysql]
name=mysql_repo
baseurl=https://xxx/mysql-repo/yum/mysql-5.7-community/el/$releasever/$basearch
gpgcheck=0
enable=1

5 、使用awk根据某字段去重

文本内容:

2019-01-13_12:00_index?uid=123
2019-01-13_13:00_index?uid=123
2019-01-13_14:00_index?uid=333
2019-01-13_15:00_index?uid=9710
2019-01-14_12:00_index?uid=123
2019-01-14_13:00_index?uid=123
2019-01-15_14:00_index?uid=333
2019-01-16_15:00_index?uid=9710

awk实现:

awk  -F "?" '!arr[$2]++{print}' test.txt 
2019-01-13_12:00_index?uid=123
2019-01-13_14:00_index?uid=333
2019-01-13_15:00_index?uid=9710

6、awk次数统计

文本内容:

portmapper
portmapper
portmapper
portmapper
portmapper
portmapper
status
status
mountd
mountd
mountd
mountd
mountd
mountd
nfs
nfs
nfs_acl
nfs
nfs
nfs_acl
nlockmgr
nlockmgr
nlockmgr
nlockmgr
nlockmgr

awk实现:

[root@centos111 test]# awk '{arr[$0]++}END{for(i in arr){print arr[i],i}}'  test.txt 
4 nfs
2 status
5 nlockmgr
6 portmapper
2 nfs_acl
6 mountd

7、awk统计TCP连接状态数量

文本内容:
netstat -antup
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:9000          0.0.0.0:*               LISTEN      1105/php-fpm: maste 
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      719/rpcbind         
tcp        0      0 192.168.122.1:53        0.0.0.0:*               LISTEN      1583/dnsmasq        
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1103/sshd           
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      1101/cupsd          
tcp        0      0 127.0.0.1:6010          0.0.0.0:*               LISTEN      1667/sshd: root@pts 
tcp        0     36 192.168.159.200:22      192.168.159.1:58404     ESTABLISHED 1667/sshd: root@pts 
tcp6       0      0 :::3306                 :::*                    LISTEN      1377/mysqld         
tcp6       0      0 :::111                  :::*                    LISTEN      719/rpcbind         
tcp6       0      0 :::22                   :::*                    LISTEN      1103/sshd           
tcp6       0      0 ::1:631                 :::*                    LISTEN      1101/cupsd          
tcp6       0      0 ::1:6010                :::*                    LISTEN      1667/sshd: root@pts 
tcp6       0      0 :::33060                :::*                    LISTEN      1377/mysqld         
udp        0      0 192.168.122.1:53        0.0.0.0:*                           1583/dnsmasq        
udp        0      0 0.0.0.0:67              0.0.0.0:*                           1583/dnsmasq        
udp        0      0 0.0.0.0:111             0.0.0.0:*                           719/rpcbind         
udp        0      0 0.0.0.0:5353            0.0.0.0:*                           728/avahi-daemon: r 
udp        0      0 0.0.0.0:42752           0.0.0.0:*                           728/avahi-daemon: r 
udp        0      0 127.0.0.1:323           0.0.0.0:*                           743/chronyd         
udp        0      0 0.0.0.0:881             0.0.0.0:*                           719/rpcbind         
udp6       0      0 :::111                  :::*                                719/rpcbind         
udp6       0      0 ::1:323                 :::*                                743/chronyd         
udp6       0      0 :::881                  :::*                                719/rpcbind    

awk实现:

[root@centos111 test]# netstat -antup | awk '/^tcp/{arr[$6]++}END{for(i in arr){print arr[i],i}}'
12 LISTEN
1 ESTABLISHED

8、awk统计日志中各IP访问非200状态码的次数

日志数据:

111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 301 169 
111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 200 169
111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 301 169 
111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 301 169 
111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 200 169 111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 404 169 
111.202.100.141 - - [2019-11-07T03:11:02+08:00] "GET /robots.txt HTTP/1.1" 200 169  

统计非200状态码的IP,并取次数最多的前10个IP。

awk实现:

[root@centos111 test]# awk '$8!=200{arr[i]++}END{for(i in arr)print arr[i],i}' log.txt |sort -klnr | head
3 

9、awk统计独立IP

url 访问IP 访问时间 访问人

文件内容:

a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
b.com.cn|202.109.134.23|2015-11-20 20:34:48|guest
c.com.cn|202.109.134.24|2015-11-20 20:34:48|guest
a.com.cn|202.109.134.23|2015-11-20 20:34:43|guest
a.com.cn|202.109.134.24|2015-11-20 20:34:43|guest
b.com.cn|202.109.134.25|2015-11-20 20:34:48|guest

需求:统计每个URL的独立访问IP有多少个(去重),并且要为每个URL保存一个对应的文件,得到的结果类似:

a.com.cn 2

b.com.cn 2

c.com.cn 1

并且有三个对应的文件:

a.com.cn.txt
b.com.cn.txt
c.com.cn.txt

awk实现:

script.sh:

[root@centos111 test]# cat script.sh 
BEGIN{FS="|"
}
!arr[$1,$2]++{arr1[$1]++
}
END {
for (i in arr1) {print i,arr1[i] > (i".txt")}
}
[root@centos111 test]# awk -f script.sh test.txt 

可以查看一下生成的文件:

[root@centos111 test]# cat a.com.cn.txt 
a.com.cn 2
[root@centos111 test]# cat b.com.cn.txt 
b.com.cn 2
[root@centos111 test]# cat c.com.cn.txt 
c.com.cn 1

10、awk处理字段缺失的数据

文本内容:

ID  name    gender  age  email          phone
1   Bob     male    28   abc@qq.com     18023394012
2   Alice   female  24   def@gmail.com  18084925203
3   Tony    male    21                  17048792503
4   Kevin   male    21   bbb@189.com    17023929033
5   Alex    male    18   ccc@xyz.com    18185904230
6   Andy    female       ddd@139.com    18923902352
7   Jerry   female  25   exdsa@189.com  18785234906
8   Peter   male    20   bax@qq.com     17729348758
9   Steven          23   bc@sohu.com    15947893212
10  Bruce   female  27   bcbd@139.com   13942943905

当字段缺失时,直接使用FS划分字段来处理会非常棘手。gawk为了解决这种特殊需求,提供了FIELDWIDTHS变量。

FIELDWIDTH可以按照字符数量划分字段。

awk实现:

[root@centos111 test]# awk '{print $4}' FIELDWIDTHS='2 2:6 2:3 2:13 2:11' test.txt

11、awk处理字段中包含了字段分隔符的数据

下面是CSV文件中的一行,该CSV文件以逗号分隔各个字段。

Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA

需求:取得第三个字段”1234 A Pretty Street, NE”。

当字段中包含了字段分隔符时,直接使用FS划分字段来处理会非常棘手。gawk为了解决这种特殊需求,提供了FPAT变量。

FPAT可以收集正则匹配的结果,并将它们保存在各个字段中。(就像grep匹配成功的部分会加颜色显示,而使用FPAT划分字段,则是将匹配成功的部分保存在字段$1 $2 $3...中)。

awk实现:

[root@centos111 test]# echo 'Robbins,Arnold,"1234 A Pretty Street, NE",MyTown,MyState,12345-6789,USA' |\
> awk 'BEGIN{FPAT="[^,]+|\".*\""}{print $1,$3}'
Robbins "1234 A Pretty Street, NE"

12、awk取字段中指定字符数量

文本内容:

16  001agdcdafasd
16  002agdcxxxxxx
23  001adfadfahoh
23  001fsdadggggg

得到:

16  001
16  002
23  001
23  002

awk实现:

[root@centos111 test]# awk '{print $1,substr($2,1,3)}' test.txt 
16 001
16 002
23 001
23 001

13、awk行列转换

文件内容:

name age
alice 21
ryan 30

转换得到:

name alice ryan
age 21 30

awk实现:

script.sh:

{for(i=1;i<=NF;i++){if(!(i in arr)){arr[i]=$i} else {arr[i]=arr[i]" "$i}}}END{for(i=1;i<=NF;i++){print arr[i]}}
[root@centos111 test]# awk -f script.sh test.txt 
me alice ryan
age 21 30

14、awk行列转换2

文件内容:

74683 1001
74683 1002
74683 1011
74684 1000
74684 1001
74684 1002
74685 1001
74685 1011
74686 1000
....
100085 1000
100085 1001

文件就两列,希望处理成

74683 1001 1002 1011
74684 1000 1001 1002
...

就是只要第一列数字相同, 就把他们的第二列放一行上,中间空格分开

awk实现:

script.sh:

{if($1 in arr){arr[$1] = arr[$1]" "$2} else {arr[$1] = $2}}
​
END{for(i in arr){printf "%s %s\n",i,arr[i]}
}
[root@centos111 test]# awk -f script.sh test.txt 
74686 1000
.... 
100085 1000 1001
74683 1001 1002 1011
74684 1000 1001 1002
74685 1001 1011

15、awk筛选给定时间范围内的日志

grep/sed/awk用正则去筛选日志时,如果要精确到小时、分钟、秒,则非常难以实现。

但是awk提供了mktime()函数,它可以将时间转换成epoch时间值。

# 2019-11-10 03:42:40转换成epoch
$ awk 'BEGIN{print mktime("2019 11 10 03 42 40")}'
1573328560

借此,可以取得日志中的时间字符串部分,再将它们的年、月、日、时、分、秒都取出来,然后放入mktime()构建成对应的epoch值。因为epoch值是数值,所以可以比较大小,从而决定时间的大小。

下面strptime1()实现的是将2019-11-10T03:42:40+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。

下面strptime2()实现的是将10/Nov/2019:23:53:44+08:00格式的字符串转换成epoch值,然后和which_time比较大小即可筛选出精确到秒的日志。、

strtime1():

[root@centos111 test]# cat script.sh 
BEGIN {which_time = mktime("2023 11 18 10 14 30")
}
{match($0,"^.*\\[(.*)\\].*",arr)tmp_time = strptime1(arr[1])if(tmp_time > which_time){print}
}
function strptime(str    ,arr,Y,M,D,H,m,S){patsplit(str,arr,"[0-9]{1,4}")Y=arr[1]M=arr[2]D=arr[3]H=arr[4]m=arr[5]S=arr[6]return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))}

 strtime2(): 

PLAINTEXT
BEGIN{# 要筛选什么时间的日志,将其时间构建成epoch值which_time = mktime("2023 11 18 10 14 30")
}{# 取出日志中的日期时间字符串部分match($0,"^.*\\[(.*)\\].*",arr)# 将日期时间字符串转换为epoch值tmp_time = strptime2(arr[1])# 通过比较epoch值来比较时间大小if(tmp_time > which_time){print }
}# 构建的时间字符串格式为:"10/Nov/2019:23:53:44+08:00"
function strptime2(str   ,dt_str,arr,Y,M,D,H,m,S) {dt_str = gensub("[/:+]"," ","g",str)# dt_sr = "10 Nov 2023 11 18 10 14 30"split(dt_str,arr," ")Y=arr[3]M=mon_map(arr[2])D=arr[1]H=arr[4]m=arr[5]S=arr[6]return mktime(sprintf("%s %s %s %s %s %s",Y,M,D,H,m,S))
}function mon_map(str   ,mons){mons["Jan"]=1mons["Feb"]=2mons["Mar"]=3mons["Apr"]=4mons["May"]=5mons["Jun"]=6mons["Jul"]=7mons["Aug"]=8mons["Sep"]=9mons["Oct"]=10mons["Nov"]=11mons["Dec"]=12return mons[str]
}

16、awk去掉/**/中间的注释

示例数据:

/*AAAAAAAAAA*/
1111
222
​
/*aaaaaaaaa*/
32323
12341234
12134 /*bbbbbbbbbb*/ 132412
​
14534122
/*cccccccccc
*/
xxxxxx /*dddddddddddcccccccccceeeeeee
*/ yyyyyyyy
5642341

script:

/\/\*/{if  (/\*\//){print gensub("(.*)/\\*.*\\*/(.*)","\\1\\2","g",$0)
}
else
{print gensub("(.*)/\\*.*","\\1","g",$0)while ( (getline) >0 ){if(/\*\//){print gensub(".*\\*/(.*)","\\1","g",$0)}}}
}
!/\/\*/{print}

awk实现: 

[root@centos111 test]# awk -f script.sh test.txt 1111
22232323
12341234
12134  13241214534122yyyyyyyy
5642341

 17、awk前后段落关系判断

从如下类型的文件中,找出false段的前一段为i-order的段,同时输出这两段。

2019-09-12 07:16:27 [-]['data' => ['http://192.168.100.20:2800/api/payment/i-order',],
]
2019-09-12 07:16:27 [-]['data' => [false,],
]
2019-09-21 07:16:27 [-]['data' => ['http://192.168.100.20:2800/api/payment/i-order',],
]
2019-09-21 07:16:27 [-]['data' => ['http://192.168.100.20:2800/api/payment/i-user',],
]
2019-09-17 18:34:37 [-]['data' => [false,],
]
PLAINTEXT
BEGIN{RS="]\n"ORS=RS
}
{if(/false/ && prev ~ /i-order/){print tmpprint}tmp=$0
}

递归正则搜索:

grep -Pz '(?s)\d+((?!2019).)*i-order(?1)+\d+(?1)+false(?1)+'

18、awk两个文件的处理

有两个文件file1和file2,这两个文件格式都是一样的。

需求:先把文件2的第五列删除,然后用文件2的第一列减去文件一的第一列,把所得结果对应的贴到原来第五列的位置,请问这个脚本该怎么编写?

file1:
50.481  64.634  40.573  1.00  0.00
51.877  65.004  40.226  1.00  0.00
52.258  64.681  39.113  1.00  0.00
52.418  65.846  40.925  1.00  0.00
49.515  65.641  40.554  1.00  0.00
49.802  66.666  40.358  1.00  0.00
48.176  65.344  40.766  1.00  0.00
47.428  66.127  40.732  1.00  0.00
51.087  62.165  40.940  1.00  0.00
52.289  62.334  40.897  1.00  0.00
file2:
48.420  62.001  41.252  1.00  0.00
45.555  61.598  41.361  1.00  0.00
45.815  61.402  40.325  1.00  0.00
44.873  60.641  42.111  1.00  0.00
44.617  59.688  41.648  1.00  0.00
44.500  60.911  43.433  1.00  0.00
43.691  59.887  44.228  1.00  0.00
43.980  58.629  43.859  1.00  0.00
42.372  60.069  44.032  1.00  0.00
43.914  59.977  45.551  1.00  0.00

awk实现:

方法1:

script:

awk '{f1 =$1if( (getline < "file2") >=0 ){$5 = $1-f1print $0}
}' file1
[root@centos111 test]# ./script.sh 
48.420 62.001 41.252 1.00 -2.061
45.555 61.598 41.361 1.00 -6.322
45.815 61.402 40.325 1.00 -6.443
44.873 60.641 42.111 1.00 -7.545
44.617 59.688 41.648 1.00 -4.898
44.500 60.911 43.433 1.00 -5.302
43.691 59.887 44.228 1.00 -4.485
43.980 58.629 43.859 1.00 -3.448
42.372 60.069 44.032 1.00 -8.715
43.914 59.977 45.551 1.00 -8.375

方法2:

script:

awk 'NR==FNR{arr[FNR]=$1}NR!=FNR{$5=$1-arr[FNR];print}
' file1 file2
[root@centos111 test]# ./script.sh 
48.420 62.001 41.252 1.00 -2.061
45.555 61.598 41.361 1.00 -6.322
45.815 61.402 40.325 1.00 -6.443
44.873 60.641 42.111 1.00 -7.545
44.617 59.688 41.648 1.00 -4.898
44.500 60.911 43.433 1.00 -5.302
43.691 59.887 44.228 1.00 -4.485
43.980 58.629 43.859 1.00 -3.448
42.372 60.069 44.032 1.00 -8.715
43.914 59.977 45.551 1.00 -8.375

 19、统计多项数据

如下内容,第一个字段是IP,第二个字段是每个访问的uri。

1.1.1.1 /index1.html
1.1.1.1 /index1.html
1.1.1.1 /index2.html
1.1.1.1 /index2.html
1.1.1.1 /index2.html
1.1.1.1 /index3.html
1.1.1.2 /index1.html
1.1.1.2 /index2.html
1.1.1.2 /index2.html
1.1.1.3 /index1.html
1.1.1.3 /index1.html
1.1.1.3 /index2.html
1.1.1.3 /index2.html
1.1.1.3 /index2.html
1.1.1.3 /index3.html
1.1.1.3 /index3.html
1.1.1.4 /index2.html
1.1.1.4 /index2.html

要求统计出每个ip访问的总次数,以及每个ip所访问的uri的次数。

期望的输出结果:

1.1.1.1 6 /index3.html 1
1.1.1.1 6 /index2.html 3
1.1.1.1 6 /index1.html 2
1.1.1.2 3 /index2.html 2
1.1.1.2 3 /index1.html 1
1.1.1.3 7 /index3.html 2
1.1.1.3 7 /index2.html 3
1.1.1.3 7 /index1.html 2
1.1.1.4 2 /index2.html 2

方法1,使用子数组。

script代码:

    {a[$1][$2]++}END{# 遍历数组,统计每个ip的访问总数for(ip in a){for(uri in a[ip]){b[ip] += a[ip][uri]}}# 再次遍历for(ip in a){for(uri in a[ip]){print ip, b[ip], uri, a[ip][uri]}}}
[root@centos111 test]# ./script.sh 
1.1.1.1 6 /index3.html 1
1.1.1.1 6 /index2.html 3
1.1.1.1 6 /index1.html 2
1.1.1.2 3 /index2.html 2
1.1.1.2 3 /index1.html 1
1.1.1.3 7 /index3.html 2
1.1.1.3 7 /index2.html 3
1.1.1.3 7 /index1.html 2
1.1.1.4 2 /index2.html 2

方法2,使用复合索引的数组。

script代码:

{a[$1]++b[$1"_"$2]++}END{for(i in b){split(i,c,"_");print c[1],a[c[1]],c[2],b[i]}
}
[root@centos111 test]# ./script.sh 
1.1.1.2 3 /index2.html 2
1.1.1.4 2 /index2.html 2
1.1.1.2 3 /index1.html 1
1.1.1.1 6 /index3.html 1
1.1.1.3 7 /index3.html 2
1.1.1.1 6 /index2.html 3
1.1.1.3 7 /index2.html 3
1.1.1.1 6 /index1.html 2
1.1.1.3 7 /index1.html 2

20、处理段落

文件内容如下:

{ "ent_id" : MinKey, "_id" : MinKey } -->> {"ent_id" : NumberLong("aaaaa"),"_id" : ObjectId("bbbbb")
} on : shard04 Timestamp(685, 0)
{"ent_id" : NumberLong("ccccc"),"_id" : ObjectId("ddddd")
} -->> {"ent_id" : NumberLong("eeeee"),"_id" : ObjectId("fffff")
} on : shard04 Timestamp(331, 1)
{"ent_id" : NumberLong("ggggg"),"_id" : ObjectId("hhhhh")
} -->> {"ent_id" : NumberLong("iiiii"),"_id" : ObjectId("jjjjj")
} on : shard04 Timestamp(680, 0)

期望结果:

MinKey,MinKey,NumberLong("aaaaa"),ObjectId("bbbbb"),shard04
NumberLong("ccccc"),ObjectId("ddddd"),NumberLong("eeeee"),ObjectId("fffff"),shard04
NumberLong("ggggg"),ObjectId("hhhhh"),NumberLong("iiiii"),ObjectId("jjjjj"),shard04

script:

BEGIN{# 以Timestamp...为输入记录分隔符,一次读取一段RS=" Timestamp\\([0-9]+, [0-9]\\)"
}
{# 将一段中所有冒号后的内容保存到数组patsplit($0,arr,": ([0-9a-zA-Z\"\\(\\)])+")for(i in arr){# 移除冒号,并使用逗号分隔串联各元素str = str gensub(": ","","g",arr[i])","}# 移除尾部逗号print(substr(str,1,length(str)-1))str=""}
[root@centos111 test]# awk -f script.sh test.txt 
ObjectId("bbbbb"),shard04,MinKey,MinKey,NumberLong("aaaaa")
ObjectId("fffff"),shard04,NumberLong("ccccc"),ObjectId("ddddd"),NumberLong("eeeee")
ObjectId("jjjjj"),shard04,NumberLong("ggggg"),ObjectId("hhhhh"),NumberLong("iiiii")

使用Perl或Ruby则更简单:

perl -0nE 'BEGIN{$,=","}say $& =~ /: \K[^\s,]+/g while /{.*?} on : \S+/sg' test.log
ruby -ne 'BEGIN{$/=nil};$_.scan(/{.*?} on : \S+/m){|s|puts s.scan(/: \K[^\s,]+/).join(",")}' test.log

到这里Linux三剑客就全部介绍完毕了,最后再总结一下这三种:

总结

        grep基本是以行为单位处理文本的; 而awk可以做更细分的处理,通过指定分隔符将一行(一条记录)划分为多个字段,以字段为单位处理文本。

grep功能简单,就是一个简单的正则表达式的匹配。

grep可以理解为主要作用是在一个文件中查找过滤需要的内容

    sed是一个非交互性文本流编辑器。它编辑文件或标准输入导出的文本拷贝。sed编辑器按照一次处理 一行的方式来处理文件(或者输入)并把输出送到屏幕上。你可以在vi和ex/ed编辑器里识别他的命令。sed把当前正在处理的行保存在一个临时缓存里,这个缓存叫做模式空间。一但sed完成了对模式空间里的行的处理(即对该行执行sed命令),就把模式空间的行送到屏幕上(除非该命令要删除该行活禁止打印)。处理完该行之后,从模式空间里删除它,然后把下一行读入模式空间,进行处理,并显示。当输入文件的最后一行处理完后,sed终止。通过把每一行存在一个临时缓存里并编辑该行,初始文件不会被修改或被破坏。

AWK的功能是什么?

与sed和grep很相似,awk是一种样式扫描与处理工具,但其功能却大大强于sed和grep。

awk中支持C语法,可以有分支条件判断、循环语句等,相当于一个小型编程语言。

awk功能比较多是一个编程语言了。

awk提供了极其强大的功能:它几乎可以完成grep和sed所能完成的全部工作,同时,它还可以可以进行样式装入、流控制、数学运算符、进程控制语句甚至于内置的变量和函数。它具备了一个完整的语言所应具有的几乎所有精美特性。实际上,awk的确拥有自己的语言:awk程序设计语言,awk的三位创建者已将它正式定义为:样式扫描和处理语言。 使用awk的第一个理由是基于文本的样式扫描和处理是我们经常做的工作,awk所做的工作有些象数据库,但与数据库不同的是,它处理的是文本文件,这些文件没有专门的存储格式,普通的人们就能编辑、阅读、理解和处理它们。而数据库文件往往具有特殊的存储格式,这使得它们必须用数据库处理程序来处理它们。既然这种类似于数据库的处理工作我们经常会遇到,我们就应当找到处理它们的简便易行的方法,UNIX有很多这方面的工具,例如sed 、grep、sort以及find等等,awk是其中十分优秀的一种。

  使用awk的第二个理由是awk是一个简单的工具,当然这是相对于其强大的功能来说的。的确,UNIX有许多优秀的工具,例如UNIX天然的开发工具C语言及其延续C++就非常的优秀。但相对于它们来说,awk完成同样的功能要方便和简捷得多。这首先是因为awk提供了适应多种需要的解决方案:从解决简单问题的awk命令行到复杂而精巧的awk程序设计语言,这样做的好处是,你可以不必用复杂的方法去解决本来很简单的问题。例如,你可以用一个命令行解决简单的问题,而C不行,即使一个再简单的程序,C语言也必须经过编写、编译的全过程。其次,awk本身是解释执行的,这就使得awk程序不必经过编译的过程,同时,这也使得它与shell script程序能够很好的契合。最后,awk本身较C语言简单,虽然awk吸收了C语言很多优秀的成分,熟悉C语言会对学习awk有很大的帮助,但awk本身不须要会使用C语言——一种功能强大但需要大量时间学习才能掌握其技巧的开发工具。

  使用awk的第三个理由是awk是一个容易获得的工具。与C和C++语言不同,awk只有一个文件(/bin/awk),而且几乎每个版本的UNIX都提供各自版本的awk,你完全不必费心去想如何获得awk。但C语言却不是这样,虽然C语言是UNIX天然的开发工具,但这个开发工具却是单独发行的,换言之,你必须为你的UNIX版本的C语言开发工具单独付费(当然使用D版者除外),获得并安装它,然后你才可以使用它。

  基于以上理由,再加上awk强大的功能,我们有理由说,如果你要处理与文本样式扫描相关的工作,awk应该是你的第一选择。在这里有一个可遵循的一般原则:如果你用普通的shell工具或shell script有困难的话,试试awk,如果awk仍不能解决问题,则便用C语言,如果C语言仍然失败,则移至C++。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/147580.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis学习笔记17:基于spring data redis及lua脚本批处理scan指令查询永久有效的key

Redis的KEYS和SCAN指令都可以用于在数据库中搜索匹配指定模式的键。然而&#xff0c;它们之间有一些关键的区别&#xff1b; KEYS指令会在整个数据库中阻塞地执行匹配操作&#xff0c;并返回匹配的键列表。如果数据库很大&#xff0c;或者匹配的键很多&#xff0c;将会对性能产…

LeetCode【4】寻找两个正序数组中位数

题目&#xff1a; 思路&#xff1a; https://blog.csdn.net/a1111116/article/details/115033098 代码&#xff1a; public double findMedianSortedArrays(int[] nums1, int[] nums2) {int[] ints Arrays.copyOf(nums1, nums1.length nums2.length);System.arraycopy(nums2…

Python学习笔记--Python关键字yield

原文:http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained 注:这是一篇 stackoverflow 上一个火爆帖子的译文 问题 Python 关键字 yield 的作用是什么?用来干什么的? 比如,我正在试图理解下面的代码: def node._get_child_candidates(self,…

【Unity】XML文件的解析和生成

目录 使用XPath路径语法解析 使用xml语法解析 XML文件的生成 XML文件是一种常用的数据交换格式&#xff0c;它以文本形式存储数据&#xff0c;并使用标签来描述数据。解析和生成XML文件是软件开发中常见的任务。 解析XML文件是指从XML文件中读取数据的过程。在.NET中&#…

10. Spring源码篇之BeanPostProcessor

简介 在Bean的创建过程中会有很多的后置处理器&#xff0c;例如实例化前、实例化后、初始化前、初始化后&#xff0c;属性填充等&#xff0c;这些都是通过BeanPostProcessor来实现的 那么既然每个Bean都有有这些生命周期&#xff0c;这些BeanPostProcessor肯定需要提前知道&a…

ClickHouse 语法优化规则

ClickHouse 的 SQL 优化规则是基于RBO(Rule Based Optimization)&#xff0c;下面是一些优化规则 1 准备测试用表 1&#xff09;上传官方的数据集 将visits_v1.tar和hits_v1.tar上传到虚拟机&#xff0c;解压到clickhouse数据路径下 // 解压到clickhouse数据路径 sudo tar -xvf…

图数据库Neo4J 中文分词查询及全文检索(建立全文索引)

Neo4j的全文索引是基于Lucene实现的&#xff0c;但是Lucene默认情况下只提供了基于英文的分词器&#xff0c;下篇文章我们在讨论中文分词器&#xff08;IK&#xff09;的引用&#xff0c;本篇默认基于英文分词来做。我们前边文章就举例说明过&#xff0c;比如我要搜索苹果公司&…

基于SpringBoot+Redis的前后端分离外卖项目-苍穹外卖(五)

公共字段自动填充 1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3 步骤三 1.4 功能测试 1.1 问题分析 在前面我们已经完成了后台系统的员工管理功能和菜品分类功能的开发&#xff0c;在新增员工或者新增菜品分类时需要设置创建时间、创建人、修改时间、修…

【JavaScript】fetch 处理流式数据,实现类 chatgpt 对话

本文只包含最基础的请求后端大佬给得对话接口&#xff0c;大部分模型的传参是差不多的&#xff0c;核心还是如何处理 fetch 获取的流数据 import { defineStore } from pinia; import { ElMessage } from element-plus;type Role system | user | assistant; export interfac…

社区分享|杭银消费金融基于MeterSphere开展接口自动化测试

杭银消费金融有限公司&#xff08;以下简称“杭银消费金融”&#xff09;成立于2015年12月&#xff0c;是经中国银保监会批准&#xff0c;由杭州银行作为主发起人&#xff0c;联合滴滴出行、中国银泰等企业组建的持牌消费金融机构&#xff0c;注册资本为25.61亿元。杭银消费金融…

Python武器库开发-flask篇之Get与Post(二十五)

flask篇之Get与Post(二十五) 在Flask中通过request对象请求相关的数据,在正常的网页请求的过程中&#xff0c;有两种请求的方式&#xff0c;Get和Post Get请求 我们现在来看看在Flask中是如何以Get方式得到我们想要的值的&#xff0c;通过request.args可以获取Get请求中的所…

深入理解网络协议:通信世界的基石

&#x1f482; 个人网站:【 海拥】【神级代码资源网站】【办公神器】&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交流的小伙伴&#xff0c;请点击【全栈技术交流群】 在当今数字化时代&#xff0c;网络协议是连接世…

openGauss通过VIP实现的故障转移

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

机器学习笔记 - Ocr识别中的文本检测EAST网络概述

一、文本检测 文本检测简单来说就是找到图像中可以出现文本的区域。例如,请参见下图,其中在检测到的文本周围绘制了绿色边框。 在进行文本检测时,你可能会遇到两种情况 具有结构化文本的图像:这是指具有干净/均匀背景和常规字体的图像。文本大多密集,行结构正确,…

php连接sqlserver 安装sqlserver 驱动windows系统

第一步下载Windows 上的 Microsoft ODBC Driver for SQL Server ODBC 驱动程序 Microsoft ODBC Driver for SQL Server 直接下载安装即可&#xff0c;安装后可查看安装版本 第二步&#xff1a;下载php_sqlsrv 驱动 安装解压后&#xff0c;会有对应php版本的驱动文件&#xf…

Python hashlib 模块详细教程:安全哈希与数据完整性保护

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python hashlib 模块详细教程&#xff0c;文章6500字&#xff0c;阅读大约17分钟&#xff0c;大家enjoy~~ hashlib模块为Python提供了一种简便的方式来使用各种哈希算法&…

【科技素养】蓝桥杯STEMA 科技素养组模拟练习试卷C

单选题 1、A right triangle has a side that is 5cm long, and its hypotenuse is 13cm long.The area of the triangle is &#xff08;&#xff09;. A、30 cm2 B、60 cm2 C、65 cm2 D、32.5 cm2 答案&#xff1a;A 2、一位旅客安检后走在前往登机口的路上。路途中一部…

leetcode系列(双语)003——GO无重复字符的最长子串

文章目录 003、Longest Substring Without Repeating Characters个人解题官方解题扩展 003、Longest Substring Without Repeating Characters 无重复字符的最长子串 Given a string s, find the length of the longest substring without repeating characters. 给定一个字符…

【Linux】进程替换|exec系列函数

文章目录 一、看一看单进程版的进程替换二、进程替换的原理三、多进程版——验证各种程序替换接口exec系列函数execlexeclpexecvexecvp tipsexecleexecve 四、总结 一、看一看单进程版的进程替换 #include<stdio.h> #include<unistd.h> #include<stdlib.h>i…

电子学会C/C++编程等级考试2021年12月(一级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:输出整数部分 输入一个双精度浮点数f, 输出其整数部分。 时间限制:1000 内存限制:65536输入 一个双精度浮点数f(0 < f < 100000000)。输出 一个整数,表示浮点数的整数部分。样例输入 3.8889样例输出 3 答案: //参…