`

bash编程之 awk格式化输出

 
阅读更多

awk命令:

 

Linux文本处理三剑客:grep sed awk

awk gawk: 报表生成器,格式化文本输出

 

 

基本用法:

gawk [options] 'program' file file ...

其中program格式为: PATTERN{ACTION_STATEMENT},ACTION_STATEMENT由语句组成,语句分隔符是;

其中ACTION包含: print, printf

# awk -F: '$3>50{print $0}' /etc/passwd  输出uid大于50的行

 

 

选项:

-F[]:指明输入字段分隔符; 不使用-F时默认以空格为字段分隔符

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

gawk  -F: '{print $1,$3,"user"}'  /etc/passwd

-v  var=var  给变量赋值

 

 

1、awk的输出命令print

print item1, item2, ...

要点:

(1) 各item间使用逗号分隔,而输出时则使用输出分隔符分隔;

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

(3) print后面的item如果省略,相当于print $0;  输出“空白”,使用print "";

 

 

2、变量

2.1 内置变量

FS: input field seperator(输入时的字段分隔符),默认为空白字符;

gawk  -v FS=":" '{print $1,$3}'  /etc/passwd

 

RS:input record separator(输入时文件的换行符), 默认为换行符;

awk  -v RS=" " '{print $0}'  /etc/passwd

 

OFS: output field seperator(输出时的字段分割符),默认为空白字符;

 

ORS:output record separator(输出时文件换行符), 默认为换行符;

 

NF: number of field in current record,字段数;

awk  '{print NF}' /etc/passwd   输出字段个数

awk  '{print $NF}' /etc/passwd  输出最后一个字段

 

NR:行数,所有文件统一计数;

awk '{print NR}'  /etc/passwd /etc/issue

awk '{print NR,$0}'  /etc/passwd /etc/issue  在每一行前加上行号

 

FNR:行数,各文件分别计数;

awk '{print FNR}'  /etc/passwd /etc/issue

awk '{print FNR,$0}' /etc/passwd /etc/issue

 

FILENAME:当前文件名;

awk '{print FILENAME,$0}' /etc/passwd /etc/issue  在每一行前加上文件名

 

ARGC:命令行参数的个数;

awk  '{print ARGC}' /etc/issue 

 

ARGV:数组,保存了命令行参数;

awk  '{print ARGV[0]}' /etc/issue

 

 

2.2 自定义变量

-v var=val: 变量名区分字符大小写

定义变量的位置:

(1) 可以在program中定义变量;

awk '{file="passwd";print file,$1}' /etc/passwd

(2) 通过-v选项定义变量;

awk -v file="passwd" '{print file,$1}' /etc/passwd

 

 

3、printf命令

格式: printf format, item1, item2, ...

awk  'BEGIN{printf "%d\n",6}'

要点:

(1) format是必须的;

(2) 不会自动换行,需显式给定行分隔符;

(3) format中需要分别为后面的每个item指定一个格式符;

 

格式符:都以%开头,后跟一个字符

%c: 显示字符的ASCII码;

%d,%i: 显示十进制整数;

%e, %E: 科学计数法显示数值;

%f: 显示为浮点数;

%g, %G: 以科学计数法格式或浮点数格式显示数值;

%s: 字符串

%u: 无符号的整数

%%: 显示%自身

 

修饰符:

#[.#]: 第一个#指定显示宽度,例如%30s;第二个#表示小数点后的精度;

awk -F: '{printf "%20s:%5d\n",$1,$3}' /etc/passwd

-: 左对齐

awk -F:  '{printf "%20s:%-5d\n",$1,$3}' /etc/passwd

 

 

4、操作符:

算术操作符:

x+y, x-y, x*y, x/y, x^y, x%y

-x: 负值

+x: 转换为数值

 

字符串操作:字符串连接

 

赋值操作符:

=, +=, -=, *=,  /=,  %=, ^=

++, --

 

比较操作符:

>, >=, <. <=, ==, !=

 

模式匹配符:

~    

!~

# awk -F: '$1~/root/{print $7}' /etc/passwd   让$1匹配模式/root/

 

逻辑操作符:

&&

||

 

条件表达式:

selector?if-true-expression:if-false-expression

例子:~]# awk -F: '{$3>=500?usertype="common user":usertype="sysuser or admin";printf "%20s:%-s\n",$1,usertype}' /etc/passwd

 

函数调用:

function_name(argu1,argu2,...)

 

 

5、PATTERN

(1) /regular expression/: 仅处理能够被/regular expression/所匹配到的行;

awk -F: '/^\<root\>/{print $3}' /etc/passwd

 

(2) relational expression:关系表达式,有真假之分,一般来说,其结果为非0或非空字符串时为“真”,否则,为“假”;

awk -F: '$3>=500{print $1,$3}' /etc/passwd

awk -F: '$5~/root/{print $0}' /etc/passwd

 

(3) line ranges:行范围,类似sed或vim的地址定界法;startline, endline

 

(4) BEGIN/END: 特殊模式,仅在awk运行程序之前执行一次(BEGIN),或仅在awk运行程序之后执行一次(END);

awk  -F: 'BEGIN{print "username","shell\n"----------------}$7~/bash\>/{print $1,$7}END{print "--------------\n"}' /etc/passwd

awk  -F: 'BEGIN{username="username";shell="shell";printf "%10s%10s\n",username,shell;print "-----------"}$7~/bash\>/{printf "%10s%10s\n",$1,$7}END{print "---------------"}' /etc/passwd

 

(5) empty: 空模式,匹配任意行;

 

 

6、常用的action

(1) 表达式

(2) 控制语句

(3) 输入语句

(4) 输出语句

 

 

7、控制语句

if (condition) statement [ else statement ]

while (condition) statement

do statement while (condition)

for (expr1; expr2; expr3) statement

for (var in array) statement

break

continue

delete array[index]

delete array

exit [ expression ]

{ statements }

 

7.1 if-else

用法:对awk取得的整行或行中的字段做条件判断;

语法:

if (condition) statement [ else statement ] 

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

# awk -F: '{if ($3>=500) print $1," is a common user." }' /etc/passwd

# awk -F: '{if ($3>=500) {print $1," is a common user."} else {print $1," is a system user or admin."}}' /etc/passwd

# awk '{if (NF>6) print NF, $0 }' /etc/inittab

 

 

7.2 while循环

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

语法:while (condition) statement

while (condition) { statements }

条件为真时进行循环,直到为假退出;

# awk '{i=1;while(i<=NF){printf "%20s:%d\n",$i,length($i); i++}}' /etc/inittab

# awk '{i=1;while(i<=NF){if (length($i)>5) {printf "%20s:%d\n",$i,length($i);} i++}}' /etc/inittab

 

 

7.3 do-while循环

语法:do statement while (condition)

do { do-while-body }  while (condition)

意义:至少执行一次循环体;

 

 

7.4 for循环

语法:for (expr1; expr2; expr3) statement

for (expr1; expr2; expr3) { statements }

# awk '{for(i=1;i<=NF;i++) {printf "%s:%d\n", $i, length($i)}}' /etc/inittab

for循环在awk中有一个专用于遍历数组元素:

语法:for (var in array) { for-body }

 

 

7.5 switch

语法:switch (expression) {case VALUE or /REGEXP/: statement; ...; default: statementN}

 

 

7.6 break and continue

break [n]: 退出当前循环

continue:提前结束本轮循环,直接进入下轮循环

 

 

7.7 next

提前结束对本行的处理而进入下一行的处理

~]# awk -F: '{if($3%2!=0) next;print $1,$3}' /etc/passwd

 

 

8、Array

关联数组:array[index-expression]

index-expression:  可以使用任意字符串, 注意: 如果用数字索引,index-expression从1开始

如果某数组元素事先不存在,在引用时,awk会自动创建此元素并将其值初始化为空串,因此,若要判断数组是否存在某元素,要使用“index in array”进行;

a[mon]="Monday"

print a[mon]

 

要遍历数组中的每个元素,使用: for (var in array) { for body },注意:var会遍历array的每一个索引,print array[var]

例子:统计每一行中各单词分别出现的次数

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

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

# ss -tan | awk '!/^State/{state[$1]++}END{for (i in state) {print i,state[i]}}'

# netstat -tan | awk '/^tcp/{state[$NF]++}END{for(i in state){print i,state[i]}}'

 

练习:统计httpd访问日志中,每个IP出现的次数;

~]# awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' /var/log/httpd/access_log 

 

 

9、函数

9.1 内置函数

数值处理:

rand(): 返回0和1之间一个随机数;

 

字符串处理:

length([s]): 返回指定字符串的长度

sub(r, s [, t]):以r所表示的模式来查找t字符串中的匹配,将其第一次出现替换同s所表示的字符串;

sub(ab,AB,$0)

gsub(r, s [, t]):以r所表示的模式来查找t字符串中的匹配,将其所有的出现均替换同s所表示的字符串;

split(s, a [, r]): 以r为分隔符切割字符串s,并将切割的结果保存至a表示数组中;

# netstat -tan | awk '/^tcp/{len=split($5,client,":");ip[client[len-1]]++}END{for(i in ip){print i,ip[i]}}'

substr(s, i [, n]): 从s表示的字符串中取子串,从i开始,取n个字符;

 

时间类的函数:

systime(): 取时间戳;

 

位运算函数:

and(v1,va2): 

 

 

9.2 自定义函数

function f_name(p,q) 

{

...

}

 

 

 

书面作业:

文件名awkfile

++++++++++++++++

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.显示所有电话号码

awk -F: '{print $2}' awkfile

 

2.显示Dan的电话号码

awk -F: '/Dan/{print $2}' awkfile

  

3.显示Susan的名字和电话号码

awk -F: '/Susan/{print $1,$2}' awkfile

  

4.显示所有以D开头的姓

awk '$2~/^D/{split($2,arr,":"); print arr[1]}' awkfile

  

5.显示所有以一个C或E开头的名

awk '$1~/^[CE]/{print $1}' awkfile

 

6.显示所有只有四个字符的名

awk '{if(length($1)==4) print $1}' awkfile

 

7.显示所有区号为916的人名

awk -F: '$2~/^\[916\]/{print $1}' awkfile

  

8.显示Mike的捐款.显示每个值时都有以$开头.如$250$100$175

awk -F: '$1~/^Mike/{printf "$%s $%s $%s\n", $3, $4, $5}' awkfile

  

9.显示姓,其后跟一个逗号和名,如Jody,Savage

awk -F: '{split($1, arr, " "); printf "%s,%s\n", arr[1],arr[2]}' awkfile

分享到:
评论

相关推荐

    linux bash之 awk用法

    假设我们需要处理一个日志文件,统计其中某个特定关键词的出现次数,并对每行数据进行格式化输出。下面是一个示例Awk脚本: ```awk #!/bin/awk -f BEGIN { FS = ":"; # 设置字段分隔符为冒号 count = 0; # 初始化...

    Bash+Sed+Awk(1).pdf

    Bash脚本可用于执行文件查找、文本处理、格式化控制字符、脚本执行原理、元字符、正则表达式以及使用grep家族工具进行模式匹配。Bash脚本的编写需要对Shell的内建变量、自定义变量、Here Document、重定向、管道以及...

    Linux下BASH、AWK编程视频教程.zip

    在IT领域,Linux操作系统是广泛应用于服务器管理和自动化任务的重要平台,而BASH(Bourne-Again SHell)和AWK则是Linux系统中的两种强大的命令行工具。本篇将围绕"Linux下BASH、AWK编程视频教程"这个主题,深入探讨...

    awk promgramming&bash programming

    例如,bash脚本可以读取文件、处理文件列表,然后用awk进行特定的数据分析和格式化。这种结合使得数据处理能力大大增强,尤其适合于日志分析、报告生成和自动化工作流程。 在提供的`awk programming.rar`文件中,...

    bash编程实例

    ### bash编程实例:基础知识与应用场景 #### 一、Shell与Bash简介 Shell是一种命令解释器,也是操作系统内核与用户之间的桥梁。它不仅能够解释并执行用户输入的命令,而且还是一种强大的编程语言。通过创建一系列...

    awk教程所速度

    在输出时,awk提供了非常丰富的格式化功能,例如使用printf函数可以指定输出格式,并使用转义序列和格式说明符来定义输出的样式,如字段宽度、左对齐、精度值等。 awk还具备大量的内置函数,这些函数可以分为数值...

    The AWK Programming Language 中文版

    还可以进行字符串拼接和格式化输出: ```awk awk '{total += $2*$3; count++} END {print total, total/count}' input-file ``` ### AWK流程控制语句 AWK具有完整的流程控制语句,如 `if-else`、`while`、`for` 等...

    Linux高级bash编程

    高级bash编程 高级Bash脚本编程指南(一) 目录 ++++ 第一部分. 热身 1. 为什么使用shell编程 2. 带着一个Sha-Bang出发(Sha-Bang指的是#!) 2.1. 调用一个脚本 2.2. 初步的练习 第二部分. 基本 3. 特殊...

    sed & awk 汇总

    - 格式化输出,类似于 `sprintf`。 **常用模式和动作:** 1. **模式**:如 `/pattern/` 用于匹配文本。 2. **条件**:`if (condition) { action }` 用于执行基于条件的动作。 3. **循环**:`for (var=start; var;...

    AWK学习笔记.doc

    AWK可以使用`getline`命令从其他文件或管道中读取数据,以及使用`print`和`printf`进行复杂的输出格式化。 **一.12 AWK与SHELL SCRIPT混合编程** AWK脚本可以嵌入到shell脚本中,与其他Unix工具配合使用,实现更...

    实践大师:UNIX awk和sed编程篇

    awk,全名“awkwards”,是一个模式扫描和处理语言,专门用于处理结构化文本数据。它的主要功能是基于用户定义的规则对输入的每一行进行分析,执行相应的操作。在日常工作中,awk常用于数据分析、日志解析、报告生成...

    linux下的awk编程

    `awk`是一种强大的文本处理工具,它在Linux环境下被广泛用于数据操作任务,例如格式化数据、验证数据有效性、查找具有特定属性的项、累加数字以及打印报告等。由于这些任务经常出现,并且通常涉及简单的机械式数据...

    shell编程---awk 培训资料

    awk的设计理念是让开发者能够快速定位和操作文件中的特定行和字段,从而实现数据的筛选、格式化输出等功能。 **awk的主要功能** 1. **行选择与输出**:awk通过匹配模式,可以轻松地从文件中选择满足条件的行进行...

    AWK实例教程 AWK实例教程中文版

    - **格式化输出**:为了提高输出的可读性,可以在字段之间插入空格或其他字符。例如`awk -F ":" '{print $1 "\t" $3}' /etc/passwd`会在用户名和用户ID之间插入制表符。 - **添加文本标签**:为了进一步增强输出的...

    shell demo及编程pdf

    6. **文本处理**:使用正则表达式和命令如`grep`, `sed`, `awk`进行文本搜索、替换和格式化。 7. **错误处理**:通过`set -e`确保脚本在遇到错误时停止执行,提高脚本的健壮性。 8. **脚本调试**:使用`set -x`...

    Awk简明教程

    除了简单的数据提取,Awk 还支持类似 C 语言 `printf` 函数的格式化输出功能。例如,我们可以按照一定的格式输出文件中的所有列: ```bash $ awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n", $1, $2, $3, $4, ...

    liunx AWK教程讲解

    AWK的基本功能包括文本处理、生成格式化报告、算术运算以及字符串操作等,这些功能使其成为Linux中不可或缺的工具。它不仅适用于软件开发人员和系统管理人员,也适合Linux爱好者使用。在进行AWK学习之前,用户需要对...

Global site tag (gtag.js) - Google Analytics