awk的基本概念
-
awk主要是用于进行数据切片
-
awk缺省的行分隔符是换行,缺省的列分隔符是连续的空格和tab,行分隔符和列分隔符都可以自定义
-
awk命令行的基本形式
awk option 'script' file1 file2 ... awk option -f scriptfile file1 file2 ...
-
awk命令的基本格式
awk [options] 'Pattern{Action}' file awk /pattern/ {actions} awk /condition/ {actions}
pattern
是正则表达式,actions
是匹配成功后的一系列操作。awk程序一行一行读出待处理文件,如果某一行与pattern
匹配,或者满足condition
条件,则执行相应的actions
;如果缺省pattern
,则actions
作用于文件的每一行 -
awk的基本语法
awk [options] 'Pattern{Action}' file
[options]
: 运行的一些参数项,可以省略Pattern{Action}
:是命令主要部分,其中Action是核心操作,Parttern有时可以省略。file
: 用于指定我们操作的格式化文本的名字,可以同时操作多个文件。
awk命令
数据准备
touch test_ip.txt
vim test_ip.txt
IP Port Num 127.0.0.1 22 12 192.178.1.1 23 1 127.0.0.1 23 12 127.0.0.1 22 33 127.0.0.1 21
action
print
命令:打印;要结合{}
一起使用$0
: 结合print
一起使用,0
表示打印全部;1
表示打印第一列(按照列分隔符);2
表示打印第二列;依次类推awk '{print $0}' test_ip.txt
,打印全部内容awk '{print $1}' test_ip.txt
, 打印第一列内容- 在
action
内被双引号包裹的信息,会被当作字符串输出
pattern
- 模式
BEGIN
模式:指定处理文本之前需要执行的操作END
模式:指定处理文本之后需要执行的操作
- 命令
awk 'BEGIN{print "IP地址", "端口号"}{print $1, $2}' test_ip.txt
awk '{print $1, $2}END{print "IP地址", "端口号"}' test_ip.txt
option
- 参数
FS
: 输入分隔符;用于指定输入的格式文本时,按照何种分隔符进行列的划分OFS
: 输出分隔符;用于输出格式文本的时候,用何种分隔符进行列的划分。-F
: 指定列分隔符-v
: 设置变量
- 命令
- 指定列分隔符为
:
,并打印第一列-
awk -F '.' '{print $1}' test_ip.txt
-
awk -v FS="." '{print $1}' test_ip.txt
-
- 指定输出分隔符为
#
,并打印第一和第二列awk -v OFS="#" '{print $1, $2}' test_ip.txt
- 指定列分隔符为
变量
- 内置变量
FS
: 输入字段分隔符,默认为空白字符OFS
: 输出字段分隔符,默认为空白字符RS
: 输出记录分隔符(输入换行符),指定输入时的换行符ORS
: 输出记录分隔符(输出换行符),输出时用指定符号代替换行符NF
: 当前行的字段的个数(即当前行被分割成了几列),字段数量NR
: 行号,当前处理的文本行的行号FNR
: 各文件分别计数的行号FILENAME
: 当前文件名ARGC
: 命令行参数的个数ARGV
: 数组,保存得失命令行所给定的各参数
awk案例
-
在
a b c d
的b
后面插入三个字段"e f g"echo "a b c d" | awk '$3="e f g"{print $0}'
-
格式化空白;移除每行的前缀、后缀空白,并将各部分左对齐
aaaa bbbb cc bbb aaa ccc ddd ffff eee gg gg dd
awk -v OFS="\t" '{$1=$1;print $0}' test.txt
-t
表示制表符;$1=$1的逻辑表示根据OFS的值重建$0
(修改字段或者修改NF的值都会导致$0重建) -
从ifconfig命令的结果中筛选出除了io网卡外的所有ipv4地址
ifconfig | awk '/inet / && !($2 ~ /^127/) {print$2}'
-
读取.ini配置文件中的某段
test_ini.txt
内容[base] this is base hello [mysql] this is mysql say mysql [python] this is python say python
查询
mysql
那一段解一: awk '/mysql/, !/\[.*\]/' test_ini.txt
解二: 1.awk 文件 index($0, "[mysql]"){ print while ((getline var) > 0){ if (var ~ /\[.*\]/){ exit } print var } } 命令:awk -f 1.awk test_ini.txt
-
根据某字段去重
1.txt
2019-01-13_12:00_index?uid=123 2019-01-13_13:00_index?uid=123 2019-01-13_14:00_index?uid=123 2019-01-13_12:00_index?uid=9710 2019-01-13_12:00_index?uid=333
命令:
awk -F "?" '{arr[$2]=arr[$2]+1;if(arr[$2]==1){print}}' 1.txt
-
次数统计
awk -F "?" '{arr[$2]=arr[$2]+1}END{for( i in arr){print arr[i], i}}' 1.txt
-
统计TCP连接状态数量
netstat | awk '/^tcp/{arr[$6]=arr[$6]+1}END{for(i in arr){print arr[i], i}}'
-
统计独立IP
1.txt
a.com.cn|202.109.134.123 b.com.cn|202.109.134.123 a.com.cn|202.109.134.124 a.com.cn|202.109.134.125 b.com.cn|202.109.134.124 a.com.cn|202.109.134.123
1.awk
BEGIN{ FS="|" } { if(!arr[$1,$2]++){ arr1[$1]++ } } END{ for( i in arr1){ print i, arr1[i] } }
命令:
awk -f 1.awk 1.txt
-
处理字段缺失的数据
1.txt
ID name gender age email phone 1 Alice female 28 abc@qq.com 110 2 Bob 20 def@qq.com 3 tony male 21 11111@qq.com 130 4 alex male 22 140
1.awk
BEGIN{ FIELDWIDTHS="2 7 8 5 14 7" } { print $4,$5,$6 } # FIELDWIDTHS 设置每列的字符数,假设不存在内容,会强制写空字符;上面也可以写成FIELDWIDTHS="2 2:5 2:6 2:3 3:12 2:5"
命令:
awk -f 1.awk 1.txt
-
处理字段中包含了字段分隔符的数据
echo 'robbins,arnold,"1234 A pretty street, Ne",myTown,mystates,12345-6789,usa' | awk 'BEGIN{FPAT="[^,]+|\".*\""}{print $1,$3}'
取第三列
-
取字段中指定字符数量
取第一个字段,和第二个字段前三位
echo '16 001agdcdafasd' | awk '{print $1,substr($2,1,3)}'
echo '16 001agdcdafasd' | awk 'BEGIN{FIELDWIDTHS="2 2:3"}{print $1,$2}'