awk学习笔记

     awk的工作模式:在处理文本流时,每一次从文本中读取一行数据,按指定的分隔符,对整行内容进行切片,把切片的结果赋值给内置的位置参数变量,然后可以指定对特定的字段做出特定的处理后输出。

基本语法:awk [OPTION] 'program' FILE1 FILE2....

其中program的组成方式为:PATTERN{ACTION STATEMENT},最常用的ACTION有print,printf

awk的运行方式

   1,命令行

#awk -F: '{print $1,$3}' /etc/passwd

wKiom1VcAhuAoi0KAABa10xav-Q013.jpg

   2,awk程序文件

root@localhost ~]# vim awk.script

{print $1,$3}

[root@localhost ~]# awk -f awk.script -F: /etc/passwd

  wKiom1VcA27iJGGmAABMwvERJJM407.jpg

  3,awk脚本(不常用)。

awk的常用选项

  -F[]:指明字段分隔符

  -v VAR_NAME=VALUE:变量赋值

  -f /PATN/TO/AWK_SCRIPT


输出命令print

   用法:print item1,item2...

     item的类型可以分为以下几类:字符串、变量、数值。


       1、字符串:需要用引号引用,如:print “hello”

[root@localhost ~]# awk -F: '{print "hello",$1}' /etc/passwd

wKioL1VcCI-R4TJiAACQAvDBSps093.jpg

      2、变量,需要注意的是,要显示变量值只需要print VAR_NAME即可,不需要加$,这点跟BASH有所不同,一定要搞清楚。引用变量只需使用变量名。

[root@localhost ~]# awk -v f1=hello '{print f1}' /etc/passwd

wKioL1VcCq2SxkxzAABQ_GRUOfY926.jpg

[root@localhost ~]# awk -F: -v f1=1 '{print $f1}' /etc/passwd

wKioL1VcC2qgh27lAABvZqJOKY0855.jpg

      3、数值,无需加引号

[root@localhost ~]# awk '{print 3}' /etc/passwd

wKiom1VcFwWQs_vDAABcEX6-m4U455.jpg

注意:各item之间用“,”分隔,输出的分隔符为“ ”

    (1) 各item之间需要使用逗号分隔;而输出时的分隔符为默认为空白字符;

    (2) 输出的各item可以为字符串或数值、当前记录的字段($#)、变量或awk的表达式;数值会被隐式转换为字符串进行输出;

    (3) print后面的item省略时,相当于运行“print $0”,用于输出整行;

    (4) 输出空白字符:print " "


变量

   内建变量,自定义变量

   内建变量:

  FS,RS,OFS,ORS,NF,NR,FNR

  1、 FS:input Field Seperator,输入字段分隔符,默认为空白

[root@localhost ~]# awk -v FS=":" '{print $1,$3}' /etc/passwd

wKiom1VcGXmA_kz9AABqIXTGOeU330.jpg

  使用FS可指定多重分隔符

[root@localhost ~]# vim awktest

what are you doing?
what is your name?
this is hank,lily.

wKiom1VcG2fiTVgGAAB3E7ngqlk253.jpg

   2、RS:input Recore Sperator,输入时的行分隔符,默认为换行符。

[root@localhost ~]# awk -v RS=" " '{print $0}' /etc/passwd

  3、OFS:输出时的字段分隔符,默认为空白。

wKiom1VcHfPCCQmtAACfLaqbd9w319.jpg

  4、ORS:输出时的行分隔符,默认为换行符。

  

  5、NF:Number of field in current record,当前行的字段数。

wKiom1VcH9bxIFPgAAA23ukR7XI333.jpg

  显示文本中每一行的最后一个字段

wKioL1VcIhjjfoMBAADijg9tCRM198.jpg

   NR:Number of record,行数,命令后跟的所有文件将统一计数。

wKioL1VcIvqipcCaAAA_7ytu7pU258.jpg

   FNR:文件的行数,各文件单独计数。

   FILENAME:当前正在被awk读取的文件的文件名

wKioL1VcJJTDAUgvAABpvE2fSxQ920.jpg

   ARGC:awk命令行中参数的个数,‘program’和“file”都被定义为参数

wKioL1VcJdyBpIBrAAA2w0YCLYk746.jpg

wKiom1VcJHDQCyvPAAAzMhSPQWo538.jpg

   ARGV:保存命令行参数本身

wKiom1VcJS7T0-5mAABMZHG7zHI249.jpg


  自定义变量

 1、-v VAR_NAME=VALUE

  2、在‘program’中定义。

wKioL1VcKbvTG-8hAAA8VQUV6jE466.jpg

wKiom1VcKPPi26uzAAA2jkwGxOo635.jpg


输出语句printf

  语法:printf FORMAT,item1,item2,...

  要点:

    (1) 必须提供FORMAT;

    (2) 与print语句不同,printf不会自动换行,需要显式指定换行符:\n

    (3) FORMAT中需要分别为后面的每个item指定一个格式符,否则item则无法显示;

    格式符:都以%开头,后跟单个字符;
				%c: 显示字符的ASCII码;
				%d, %i:显示为十进制整数;
				%e, %E: 科学计数法显示数值;
				%f:显示为浮点数;
				%g, %G:以科学计数法或浮点数格式显示数值;
				%s: 显示为字符串;
				%u:显示无符号整数;
				%%: 显示%符号自身;

wKioL1VcLETDAagUAABzG1rhSp4538.jpg

wKioL1VcLUTiAaoMAAD6n77HSM4551.jpg

不为item指定格式符,item无法输出

wKioL1VcLiegywL9AADNwQdMhRE995.jpg

修饰符:
				#[.#]:
					左边的#:用于指定显示宽度;
					右边的#: 显示精度;
				+:显示数值符号
				-:左对齐

wKioL1VcMl2jjRkuAAEyoWxmFfw320.jpg

wKiom1VcMPOTySh9AAEBrdDe4SM498.jpg

wKioL1VcMoDBj16JAAEtbwNWslc819.jpg

wKiom1VcMRWjdLfUAABOu1Klfa0740.jpg

wKioL1VcMxnCn1uGAABbKZEcxmg106.jpg


操作符

算术操作符:
				x+y, x-y, x*y, x/y, x^y, x%y
				-x: 负值
				+x: 转换为数值

			字符操作符:字符串连接

			赋值操作符:
				=, +=, -=, *=, /=, %=, ^=
				++, --

			比较操作符:
				>, >=, <, <=, ==, !=

			模式匹配操作符:
				~:是否能由右侧指定的模式所匹配;
				!~:是否不能由右侧指定模式所匹配;

			逻辑操作符:
				&&:与运算
				||: 或运算

			条件表达式:
				selector?if-true-expression:if-false-expression

  1、算术操作符

wKioL1VcNKXilROrAABrSDVrsjE891.jpg

  2、字符串操作符,字符串连接

  3、赋值操作符

wKioL1VcNj3xv0jfAACnP7Px4fI829.jpg

  4、条件表达式

wKioL1VcORzyqdqaAACDMI44HRU577.jpg

wKiom1VcOQzgUauqAACl3nCbOw8345.jpg


PATTERN

(1) empty:空模式,匹配所有行;
(2) /Regular Expression/:仅将ACTION应用于能够被Regular Expression所匹配到的行;
				例如:awk -F: '/^[ab]/{print $1,$3}' /etc/passwd
(3) relational expression:关系表达式,即结果为“真”、“假”的表达式, 或者其结果能类同于“真”或“假”的表达;一般来说,其结果为非0数值或非空字符串即可类同为“真”,否则,则类同为“假”;
				例如:awk -F: '$3>=500{print $1,$3}' /etc/passwd
				例如:awk -F: '$1~/root/{print $1,$3}' /etc/passwd
(4) line ranges:行范围,类似sed或vim中的地址定界方式
				startline,endline
5) BEGIN/END:两个特殊模式
				BEGIN:在文件格式化操作开始之前事先执行的一次操作;通常用于输出表头或做出一个预处理操作;
				END:在文件格式操作完成之后,命令退出之前执行的一次操作;通常用于输出表尾或做出清理操作;

wKiom1VcPMGgOfcJAABaYHpLrP4529.jpg

wKioL1VcP0aQTNMrAACKQZa-ElU955.jpg

wKioL1VcP9XBH5fOAAB07VBFDsA427.jpg

行范围

wKioL1VcRCyx1L6QAABnHn5wmJs892.jpg

wKiom1VcRHrDbzBZAAB3gvg7RMc654.jpg

wKiom1VcRYGj0_ZQAADe3_nhHNs774.jpg

wKioL1VcR5rzTzKxAABUWCl3aAY859.jpg


常用的ACTION

(1) EXPRESSIONS:例如变量赋值
(2) Control Statements:控制语句,如if, while等;
(3) Compound Statements:复合语句
(4) input statements
(5) output statements

控制语句

  if-else

语法:if (condition) statement [ else statement ]

      if (condition) {statements} [else {statements}]

wKioL1VcpI2hOzHFAABkpVDybbM484.jpg

wKioL1VcpKKCNpNEAABarQzciDs679.jpg图43

[root@localhost ~]# awk -F: '{if ($3>=500){print $1,"common"} else {print $1,"sys"}}' /etc/passwd

 wKioL1VcpPCDeinXAABdqvkWigs022.jpg

  while循环

语法:while (condition) statement
      while (condition) {statements}

通常用于在当前行的各字段间进行循环

wKiom1Vco5Gh9HybAACmaB-hu9A277.jpg


 for循环

 wKioL1VcpSCA0_8qAACCReuDBVo425.jpg


next

显示ID号为奇数的用户

wKiom1Vco7fDPYtwAABn3PcUpz8656.jpg


数组

统计一个文件中每个单词出现的次数

[root@localhost ~]# awk -F: '{for(i=1;i<=NF;i++) {count[$i]++}}END{for(j in count) {print j,count[j]}}' /etc/passwd

wKioL1VcpUHx17JOAACeMUrGy_A498.jpg

统计一个文件中每一行每个单词出现的次数

# awk '{for(i=1;i<=NF;i++) {count[$i]++};for(j in count) {print j,count[j]};delete count}' /root/count.txt

wKiom1Vco9eyXw1fAACsuSaB9HU683.jpg


你可能感兴趣的:(awk,工作模式,文本流)