代码改变世界

linux awk 使用

2014-02-10 20:20  youxin  阅读(444)  评论(0编辑  收藏  举报

awk是linux下的一个命令,他对其他命令的输出,对文件的处理都十分强大,其实他更像一门编程语言,他可以自定义变量,有条件语句,有循环,有数组,有正则,有函数等。他读取输出,或者文件的方式是一行,一行的读,根据你给出的条件进行查找,并在找出来的行中进行操作,感觉他的设计思想,真的很简单,但是结合实际情况,具体操作起来就没有那么简单了。他有三种形势,awk,gawk,nawk,平时所说的awk其实就是gawk。

 

awk: gawk - pattern scanning and processing language

 

与sed一样,均是一行一行的读取,处理

sed作用于一整行的处理,而awk将一行分成数个字段来处理

字段:一段字符串 --》一段很多字符组成了一个字符串

awk --help 

Usage: awk [POSIX or GNU style options] -f progfile [--] file ...
Usage: awk [POSIX or GNU style options] [--] 'program' file ...
POSIX options: GNU long options: (standard)
-f progfile --file=progfile
-F fs --field-separator=fs
-v var=val --assign=var=val
Short options: GNU long options: (extensions)
-b --characters-as-bytes
-c --traditional
-C --copyright
-d[file] --dump-variables[=file]
-e 'program-text' --source='program-text'
-E file --exec=file
-g --gen-pot
-h --help
-L [fatal] --lint[=fatal]
-n --non-decimal-data
-N --use-lc-numeric
-O --optimize
-p[file] --profile[=file]
-P --posix
-r --re-interval
-S --sandbox
-t --lint-old
-V --version

To report bugs, see node `Bugs' in `gawk.info', which is
section `Reporting Problems and Bugs' in the printed version.

gawk is a pattern scanning and processing language.
By default it reads standard input and writes standard output.

Examples:
gawk '{ sum += $1 }; END { print sum }' file
gawk -F: '{ print $1 }' /etc/passwd

 

    -F sepstring
                 Define the input field separator. This option shall be
                 equivalent to:

                     -v FS=sepstring

                 except that if -F sepstring and -v FS=sepstring are
                 both used, it is unspecified whether the FS assignment
                 resulting from -F sepstring is processed in command
                 line order or is processed after the last -v
                 FS=sepstring.  See the description of the FS built-in
                 variable, and how it is used, in the EXTENDED
                 DESCRIPTION section.
 

http://l.51yip.com/search/awk

 

按列求和:

Shell中,我们可以用awk实现按列求和的功能,非常简单。看下面的例子:
1.简单的按列求和

[linux@test /tmp]$ cat test

123.52
125.54
126.36

[linux@test /tmp]$ awk '{sum += $1};END {print sum}' test

375.42
2.对符合某些条件的行,按列求和

[linux@test /tmp]$ cat test

aaa 123.52
bbb 125.54
aaa 123.52
aaa 123.52
ccc 126.36
对文件test中 第一列为aaa的行求和

[linux@test /tmp]$ awk '/aaa/ {sum += $2};END {print sum}' test

370.56

更多:

http://heikezhi.com/yuanyi/why-you-should-know-just-little-awk

 

 

 

awk完整语法
awk ‘BEGIN {commands} pattern {commands}END{commands}' file1

BEGIN:处理数据前执行的命令

END:处理数据后执行的命令

pattern:模式,每一行都执行的命令

BEGIN和END里的命令只是执行一次

pattern里的命令会匹配每一行去处理
————————————————

 


原文链接:https://blog.csdn.net/qq_48391148/article/details/125602640

 

grep -e 适用于简单的正则表达式,比如搜索一个字符串中是否包含特定的关键词。例如:

grep -e 'hello' file.txt
# 将会在文件file.txt中搜索出所有包含“hello”这个关键词的行。

grep -E 则适用于复杂的正则表达式,可以使用多项选择、重复和子表达式来匹配文本。例如:

grep -E '(foo|bar)baz' file.txt
#会在文件file.txt中搜索出所有包含“foobaz”或者 “barbaz” 的行。
链接:https://blog.csdn.net/dgwxligg/article/details/129189848

 

awk常用命令

3.1 awk查看某个时间段的日志

awk ‘/^开始时间日期/,/^结束时间日期/’ nginx.log
awk支持正则表达式,比如,查询时间段2021-03-24 10:12:12 到 2021-09-24 10:12:12,
可以用awk ‘/^2021-03-24 10:12:*/,/^2021-09-24 10:12:*/’ nginx.log查询。

awk 中 分号 和 逗号的区别:

话不多说,直接举例:

 


由图可知:
,(逗号) 表示的是一个范围,就是逗号前到逗号后作为一个范围。
;(分号) 表示的是隔开,分号前 和 分号后 没有联系。

 

 

 

统计命令

# 求和
cat data|awk '{sum+=$1} END {print "Sum = ", sum}'
# 求平均
cat data|awk '{sum+=$1} END {print "Average = ", sum/NR}'
# 求最大值
cat data|awk 'BEGIN {max = 0} {if ($1>max) max=$1 fi} END {print "Max=", max}'
# 求最小值(min的初始值设置一个超大数即可)
awk 'BEGIN {min = 1999999} {if ($1<min) min=$1 fi} END {print "Min=", min}'

awk 内置变量表

 

5.3.3   [...]

  中的

  \   转义(awk中使用)

  -   表示范围。例如[0-9]包含任何数字

  ^   取反。例如[^0-9]不匹配数字。注意在grep中是使用grep –v来取反

grep ‘^[0-9]‘ /etc/inittab          查出以数字开头的行
    grep ‘[a-Z]‘ /etc/inittab            查出有字母(大小通用)的行
    grep ‘^[^0-9]‘    /etc/inittab        ^[^ ]取反的
    grep ‘x:[0-9][0-9]:’ /etc/passwd 取出UID为0-99的用户
    ls -l /dev |grep ‘tty[0-9]*$’        (*多个或0个前面的字符)

5.3.4   ^

^n - 以n开头的行

5.3.5   $

从行尾开始任务。

注意:在sed和grep中^和$并不一定总保持着自己的个性。当使用ab^c 或者是ab$c匹配时它们就确实代表着字面意思,没有任何别的含义。但在awk中则不同,^和$永远保持着自己的个性,所以在awk中如果要匹配它俩时都需要使用\来转义。

5.3.6   \{n,m\}

101

1001

10001

100001

10000001

100000001

这时候想把1001,10001,100001过滤出来。

# grep “10\{2,4\}1″ file

1001

10001

100001

1001中有2个0,100001中有4个0,所以这个大家应该明白了吧?

5.3.7   \

转义符。取消字符的特殊效果。比如我要匹配文件中的5.6。这时候我需要这样写

# grep ’5\.6′ file

5.6

如果写成

grep ’5.6′ file

5.6

506

则列出了5.6和506。

 

shell除法:

A=expr $num1 / $num2

这个时候num3=0 ,是因为是因为expr不支持浮点除法

小数点标识的方法:

num3=`echo "scale=2; $num1/$num2" | bc`
echo "num1/num2=$num3"
1
2
使用bc工具,scale控制小数点后保留几位

另一种方法

awk 'BEGIN{printf "%.2f\n",’$num1‘/’$num2‘}'
 

https://zhuanlan.zhihu.com/p/518549290

 https://zhuanlan.zhihu.com/p/518549290

https://blog.csdn.net/ljlfather/article/details/104530474/

 

 

*awk命令  

1、例如查询今天14:10:10 到14:12:59区间的日志,注意时间要用引号

1
awk '$2>"14:10:10" && $2<"14:12:59"' dubbo-elastic-job.log  

注意参数$1和$2的取值,我这里$1是指年月日,$2是指时分秒。

 

awk用法之:文本替换

awk的sub/gsub函数用来替换字符串,其语法格式是:

sub(/regexp/, replacement, target)

注意第三个参数target,如果忽略则使用$0作为参数,即整行文本。

  • 例子1:替换单个串

只把每行的第一个AAAA替换为BBBB

awk '{ sub(/AAAA/,"BBBB"); print $0 }' t.txt
  • 例子2:替换所有的串

把每一行的所有AAAA替换为BBBB

awk '{ gsub(/AAAA/,"BBBB"); print $0 }' t.txt
  • 例子3:替换满足条件的行的串

只在出现字符串CCCC的前提下,将行中所有AAAA替换为BBBB

awk '/CCCC/ { gsub(/AAAA/,"BBBB"); print $0; next }
            { print $0 }
    ' t.txt
  • 例子4:替换多个可选串

不管是AAAA,还是CCCC,全部替换为BBBB

awk '{ gsub(/AAAA|aaaa/,"BBBB"); print $0 }' t.txt
  • 例子5:全字匹配替换

全字匹配AAAA;即不匹配AAA,以及AAAAA,也就是说完整的四个字符串AAAA。

awk '{ sub(/\<AAAA\>/,"BBBB"); print $0 }' t.txt
  • 例子6:规则表达式匹配

把所有以A开头,不管后面连续包含几个A的串替换成一个字符B。

awk '{ gsub(/^A*/,"B"); print $0 }' t.txt


作者:CodingCode
链接:https://www.jianshu.com/p/d90f8a2ecd62
 
注意逗号和&是特殊字符,要转义
 

gsub函数则使得在所有正则表达式被匹配的时候都发生替换

gsub(regular expression, subsitution string, target string);简称 gsub(r,s,t)

sub匹配第一次出现的符合模式的字符串,相当于 sed ‘s//’ 。
gsub匹配所有的符合模式的字符串,相当于 sed ‘s//g’

实例一
将|分割第二个域中的数字去掉
 

$ awk '{ gsub(/test/, "mytest"); print }' testfile

$ awk '{ gsub(/test/, "mytest", $1); print }' testfile


0001|efskjfdj|EREADFASDLKJCV

实例二
/分割,取出snapshots后面知道倒数第四个之间的域(其中/的数不确定,所以不大方便直接使用awk 6,
6

7,$8来直接取,使用字段截取),.隔开 com.netfinworks.authorize
示例

/Users/yfan/Downloads/dsc20170801_jar/snapshots/com/netfinworks/authorize/authorize-service/1.0.0-SNAPSHOT/authorize-service-1.0.0-SNAPSHOT.jar
1
先设置一个变量

yfandeMacBook-Pro:pbs yfan$ test=/Users/yfan/Downloads/dsc20170801_jar/snapshots/com/netfinworks/authorize/authorize-service/1.0.0-SNAPSHOT/authorize-service-1.0.0-SNAPSHOT.jar
1
用Linux中的符号截断(##)去掉com前面的部分

yfandeMacBook-Pro:pbs yfan$ echo ${test##*snapshots/}
1
结果

com/netfinworks/authorize/authorize-service/1.0.0-SNAPSHOT/authorize-service-1.0.0-SNAPSHOT.jar
1
在用awk结合gsub去掉后面的部分(倒数第一、第二、第三域)

yfandeMacBook-Pro:pbs yfan$ echo ${test##*snapshots/}|awk -F'/' '{gsub("/"$(NF-2)"/"$(NF-1)"/"$NF,"");print}'
1
结果

com/netfinworks/authorize
1
最后再用sed用.替换/,完成目标

yfandeMacBook-Pro:pbs yfan$ echo ${test##*snapshots/}|awk -F'/' '{gsub("/"$(NF-2)"/"$(NF-1)"/"$NF,"");print}'|sed 's/\//./g'
1
结果

com.netfinworks.authorize
1
gsub说明参考:
http://blog.sina.com.cn/s/blog_67e34ceb0100ybvg.html
原文链接:https://blog.csdn.net/fyl_1024/article/details/78105597