生信小白成长记

笔记 | awk 的知识点

2018-12-24  本文已影响0人  琪音

awk

awk是一种处理文本文件的语言,用于Linux下对文本和数据进行处理。数据可以是标准输入、一个或多个文件、其他命令的输出。方式为逐行扫描,从第一行到最后一行,寻找到匹配特定模式的行进行操作。

命令格式和常用选项

命令格式

awk [options] ‘/pattern/{action}’ input-file
awk [options] -f myscript.awk input-file

常用选项

模式

awk脚本是由模式和操作组成,模式可以是以下的几种:

awk 'BEGIN {Fs = ":"; print "----header----"}/mail/{print $1} END{print “----footer----”}' /etc/passwd
  #搜索包含关键字mail的行,并打印第一个字段

打印命令
awk '{print}' e
mployee.txt 传递变量 “ $字段序号 ” 作为print的参数

awk -F ',' '{print $2}' employee.txt
指定 , 为分隔符

模式匹配
awk -F ',' '/Manager/{print $2,$3}' employee.txt

awk 内置变量

FS - 输入字段分隔符 在BEGIN区域使用
OFS 输出字符分隔符
两种方式:
awk -F ',' '{print $2,":",$3}' employee.txt
awk -F ',' 'BEGIN{OFS=":"}{print $2,":",$3}' employee.txt
RS 记录分隔符
ORS 输出记录分隔符
NR 记录序号 条数
​ 开始执行后,按照记录分隔符读取的数据次数,默认的记录分隔符为换行符,因此默认的就是读取的数据行数 Number of Record
NF 字段总数 Number of Field

FILENAME 当前处理的文件名
FNR 文件中的NR

变量操作符

变量
一元操作符 + 取正(返回数字本身) - 取反 ++ 自增 --自减
算术操作符
awk 'NR % 2 == 0' filename 取偶数
字符串操作符 “ ”
赋值操作符
比较操作符 && 且 ||或
正则表达式操作符 ~ 匹配 !~ 不匹配

分支和循环

其他

printf
printf(format, value1, value2, ..., valuen)
可以灵活简单以你期望的格式输出结果
\n 换行 \t制表符 \v垂直制表符 \b退格 \r回车符 \f换页

格式化字符
s 字符串
c 单个字符串
d 数值
e 指数
f 浮点数
g 根据值决定使用e或f中较短的输出
o 八进制
x 十六进制
% 百分号

打印指定宽度(左对齐)
awk 'BEGIN {printf "%6s\n", "Good Boy!"}'

内置函数

内置函数
int(n) 整数
log(n) 返回给定参数的自然对数
sqrt() 正平方根
三角函数 sin() cos() atan2(m,n)

常用字符串函数

使用awk进行计算

关联数组

实现类似操作
cat filename cut -f '2' | sort | uniq -c | sort
这样的操作
awk '$1 ~ /Chr1/{feature[$3] += 1};END {for (k in feature) print k "\t" featrue[k]}' filename

练习

输入file.txt内容:
Mike Harrington:[510] 548-1278:250:100:175
Christian Dobbins:[408] 538-2358:155:90:201
Susan Dalsass:[206] 654-6279:250:60:50
Archie McNichol:[206] 548-1348:250:100:175
Jody Savage:[206] 548-1278:15:188:150
Guy Quigley:[916] 343-6410:250:100:175
Dan Savage:[406] 298-7744:450:300:275
Nancy McNeil:[206] 548-1278:250:80:75
John Goldenrod:[916] 348-4278:250:100:175
Chet Main:[510] 548-5258:50:95:135
Tom Savage:[408] 926-3456:250:168:200
Elizabeth Stachelin:[916] 440-1763:175:75:300

题目为:

  1. 显示所有电话号码
  2. 显示Dan的电话号码
  3. 显示Susan的名字和电话号码
  4. 显示所有以D开头的姓
  5. 显示所有以一个C或E开头的名
  6. 显示所有只有四个字符的名
  7. 显示所有区号为916的人名
  8. 显示Mike的捐款.显示每个值时都有以开头.如250100175
  9. 显示姓,其后跟一个逗号和名,如Jody,Savage
  10. 显示第三列小于200的姓名
# 输入file.txt文件 
# 这个文件是以 : 分割
# Vim编辑器,进入后按i,粘贴内容,按esc,输入 :wq 保存文件
$ vim file.txt

$ awk -F : '{print $2}' file.txt 

# 精确匹配
$ awk -F : '$1~/Dan/{print $2}' file.txt
# 输出定义分隔符
$ awk -F: '$1~/Susan/{print$1":"$2}' file.txt 
# ^行的开头  $行的结尾
$ awk '$1~/^D/{print $1}' file.txt

# 模糊匹配   或 || 且&&
$ awk -F: '$1~/^[C||E]/{print $1}' file.txt |awk '{print $2}'
# 变量
$ awk 'length($1)=="4"{print $1}' file.txt 

# 替换 这里用sed也可以
$ awk -F"[ :]" '$3~/916/{print $1" "$2}' file.txt 

# 定义输出形式 
# 还有printf(format, value1, value2, ..., valuen)
$ awk -F:  '$1~/Mike/{print "$"$3" ""$"$4" ""$"$5}' file.txt 

# 条件
$ awk -F : '{if ($3<=200) print $1}' file.txt
上一篇下一篇

猜你喜欢

热点阅读