Ubuntu Shell命令awk程序中使用

系统 Linux
"sort -k 1" 的执行次数是 "一次". 在 b 语法中, awk将先调用 Ubuntu Shell 命令. 其执行结果将通过 pipe 送入awk程序,以上例而言, awk先让 Ubuntu Shell 执行 "ls",Ubuntu Shell 执行后将结果存于 pipe, awk指令 getline再从 pipe 中读取数据.

Ubuntu Shell 对于电脑使用的玩家的常用软件,然后我就学习及深入的研究Ubuntu Shell ,在这里和大家一起探讨Ubuntu Shell 的使用方法,希望对大家有用。

awk程序中使用 Ubuntu Shell 命令

awk程序中允许呼叫Ubuntu Shell指令. 并提供管道解决awk与系统间数据传递的问题. 所以awk很容易使用系统资源. 读者可利用这个特点来编写某些适用的系统工具.

写一个awk程序来打印出线上人数. 将下列程序建文件, 命名为 count.awk BEGIN { while ( "who" | getline ) n++ print n } 并执行下列命令 : awk -f count.awk 执行结果将会印出目前在线人数

awk 程序并不一定要处理数据文件. 以本例而言, 仅输入程序文件count.awk, 未输入任何数据文件. BEGIN 和 END 同为awk中的一种 Pattern. 以 BEGIN 为 Pattern的Actions ,只有在awk开始执行程序,尚未开启任何输入文件前, 被执行一次.(注意: 只被执行一次)

"|" 为 awk 中表示管道的符号. awk 把 | 之前的字符串"who"当成Ubuntu Shell上的命令, 并将该命令送往Ubuntu Shell执行, 执行的结果(原先应于屏幕印出者)则藉由pipe送进awk程序中. getline为awk所提供的输入指令.

其语法如下 : 语法由何处读取数据数据读入后置于getline var < file所指定的 file变量 var(var省略时,表示置于$0)getline varpipe 变量变量 var(var省略时,表示置于$0)
getline var见 注一 变量 var(var省略时,表示置于$0)
 
注一 : 当 Pattern 为 BEGIN 或 END 时, getline 将由 stdin 读取数据, 否则由awk正处理的数据文件上读取数据. getline 一次读取一行数据, 若读取成功则return 1, 若读取失败则return -1, 若遇到文件结束(EOF), 则return 0;

本程序使用 getline 所 return 的数据来做为 while 判断循环停止的条件,某些awk版本较旧,并不容许使用者改变 $0 之值. 这种版的 awk 执行本程序时会产生 Error, 读者可于 getline 之后置上一个变量 (如此, getline 读进来的数据便不会被置于 $0 ), 或直接改用gawk便可解决.

awk 程序的应用实例

本节将示范一个统计上班到达时间及迟到次数的程序. 这程序每日被执行时将读入二个文件: 员工当日到班时间的数据文件 ( 如下列之 arr.dat ) 存放员工当月迟到累计次数的文件. 当程序执行执完毕后将更新第二个文件的数据(迟到次数), 并打印当日的报表.这程序将分成下列数小节逐步完成, 其大纲如下:

在到班资料文件 arr.dat 之前增加一行抬头 "ID Number Arrvial Time", 并产生报表输出到文件today_rpt1 中.< 思考: 在awk中如何将数据输出到文件 > 将 today_rpt1 上的数据按员工代号排序, 并加注执行当日日期; 产生文件 today_rpt2 <思考 awk中如何运用系统资源及awk中Pipe之特性 >

将awk程序包含在一个Ubuntu Shell script文件中于 today_rpt2 每日报表上, 迟到者之前加上"*", 并加注当日平均到班时间;产生文件 today_rpt3 从文件中读取当月迟到次数, 并根据当日出勤状况更新迟到累计数. <思考 使用者在awk中如何读取文件数据 >

重定向输出到文件

awk中并未提供如 C 语言中之fopen() 指令, 也未有fprintf() 文件输出这样的指令. 但awk中任何输出函数之后皆可借助使用与UNIX 中类似的 I/O 重定向符, 将输出的数据重定向到指定的文件; 其符号仍为 > (输出到一个新产生的文件) 或 >> ( 添加输出的数据到文件末尾 ).

[例 :]在到班数据文件 arr.dat 之前增加一行抬头如下: "ID Number Arrival Time", 并产生报表输出到文件 today_rpt1中 建立如下文件并取名为reformat1.awk BEGIN { print " ID Number Arrival Time" > "today_rpt1" print "===========================" > "today_rpt1" } { printf(" %s %s"n", $1,$2 ) > "today_rpt1" }

执行: $awk -f reformat1.awk arr.dat 执行后将产生文件 today_rpt1, 其内容如下 : ID Number Arrival Time awk程序中, 文件名称 today_rpt1 的前后须以" (双引号)括住, 表示 today_rpt1 为一字符串常量. 若未以"括住, 则 today_rpt1 将被awk解释为一个变量名称. 在awk中任何变量使用之前, 并不须事先声明.

其初始值为空字符串(Null string) 或 0.因此程序中若未以 " 将 today_rpt1 括住, 则 today_rpt1 将是一变量, 其值将是空字符串, 这会在执行时造成错误(Unix 无法帮您开启一个以空字符串为文件名的文件).

因此在编辑awk程序时, 须格外留心. 因为若敲错变量名称,awk在编译程序时会认为是一新的变量, 并不会察觉. 因此往往会造成运行时错误. BEGIN 为awk的保留字, 是 Pattern 的一种. 以 BEGIN 为 Pattern 的 Actions 于awk程序刚被执行尚未读取数据文件时被执行一次, 此后便不再被执行.

读者或许觉得本程序中的I/O重定向符号应使用 " >>" (append)而非 " >". 本程序中若使用 ">" 将数据重导到 today_rpt1, awk 第一次执行该指令时会产生一个新档 today_rpt1, 其后再执行该指令时则把数据追加到today_rpt1文件末, 并非每执行一次就重开一个新文件.

若采用">>"其差异仅在第一次执行该指令时, 若已存在today_rpt1则 awk 将直接把数据append在原文件之末尾. 这一点, 与UNIX中的用法不同.

awk 中如何利用系统资源

awk程序中很容易使用系统资源. 这包括在程序中途调用 Ubuntu Shell 命令来处理程序中的部分数据; 或在调用 Ubuntu Shell 命令后将其产生的结果交回 awk 程序(不需将结果暂存于某个文件). 这一过程是借助 awk 所提供的管道 (虽然有些类似 Unix 中的管道, 但特性有些不同),及一个从 awk 中呼叫 Unix 的 Ubuntu Shell 命令的语法来达成的.

承上题, 将数据按员工ID排序后再输出到文件 today_rpt2 , 并于表头附加执行时的日期. awk 提供与 UNIX 用法近似的 pipe, 其记号亦为 "|". 其用法及含意如下 : awk程序中可接受下列两种语法:

[a. 语法] awk output 指令 | "Ubuntu Shell 接受的命令" ( 如 : print $1,$2 | "sort -k 1" ) [b. 语法] "Ubuntu Shell 接受的命令" | awk input 指令 ( 如 : "ls " | getline)
注 : awk input 指令只有 getline 一个. awk output 指令有 print, printf() 二个. 在a 语法中, awk所输出的数据将转送往 Ubuntu Shell , 由 Ubuntu Shell 的命令进行处理.以上例而言, print 所输出的数据将经由 Ubuntu Shell 命令 "sort -k 1" 排序后再送往屏幕(stdout).

上列awk程序中, "print$1, $2" 可能反复执行很多次, 其输出的结果将先暂存于 pipe 中,等到该程序结束时, 才会一并进行 "sort -k 1". 须注意二点 : 不论 print $1, $2 被执行几次, "sort -k 1" 的执行时间是 "awk程序结束时",

"sort -k 1" 的执行次数是 "一次". 在 b 语法中, awk将先调用 Ubuntu Shell 命令. 其执行结果将通过 pipe 送入awk程序,以上例而言, awk先让 Ubuntu Shell 执行 "ls",Ubuntu Shell 执行后将结果存于 pipe, awk指令 getline再从 pipe 中读取数据.

使用本语法时应留心: 以上例而言,awk "立刻"调用 Ubuntu Shell 来执行 "ls", 执行次数是一次. getline 则可能执行多次(若pipe中存在多行数据). 除上列 a, b 二中语法外, awk程序中其它地方如出现像 "date", "cls", "ls"... 这样的字符串, awk只把它当成一般字符串处理.

建立如下文件并取名为 reformat2.awk # 程序 reformat2.awk # 这程序用以练习awk中的pipe BEGIN { "date" | getline # Ubuntu Shell 执行 "date". getline 取得结果并以$0记录 print " Today is " , $2, $3 >"today_rpt2" print "=========================" > "today_rpt2" print " ID Number Arrival Time" >"today_rpt2" close( "today_rpt2" ) } {printf( "%s %s"n", $1 ,$2 ) | "sort -k 1 >>today_rpt2"}

执行如下命令: awk -f reformat2.awk arr.dat 执行后, 系统会自动将 sort 后的数据追加( Append; 因为使用 " >>") 到文件 today_rpt2末端. today_rpt2 内容如下 : awk程序由三个主要部分构成 :

[ i.] Pattern { Action} 指令 [ ii.] 函数主体. 例如 : function double( x ){ return 2*x } (参考第11节 Recursive Program ) [ iii.] Comment ( 以 # 开头识别之 )
awk 的输入指令 getline, 每次读取一列数据. 若getline之后未接任何变量, 则所读入之资料将以$0 记录, 否则以所指定的变量储存之.

执行 "date" | getline 后, $0 之值为 "2007年 09月 21日 星期五 14:28:02 CST",当 $0 之值被更新时, awk将自动更新相关的内建变量, 如: $1,$2,..,NF.故 $2 之值将为"09月", $3之值将为"21日".

(有少数旧版的awk不允许即使用者自行更新(update)$0的值,或者更新$0时,它不会自动更新 $1,$2,..NF. 这情况下, 可改用gawk或nawk. 否则使用者也可自行以awk字符串函数split()来分隔$0上的数据)

本程序中 printf() 指令会被执行12次( 因为有arr.dat中有12行数据), 但读者不用担心数据被重复sort了12次. 当awk结束该程序时才会 close 这个 pipe , 此时才将这12行数据一次送往系统,并呼叫 "sort -k 1 >> today_rpt2" 处理之.

awk提供另一个调用Ubuntu Shell命令的方法, 即使用awk函数system("Ubuntu Shell命令") 例如: $ awk ' BEGIN{ system("date > date.dat") getline < "date.dat"print "Today is ", $2, $3 }' 但使用 system( "Ubuntu Shell 命令" ) 时, awk无法直接将执行中的部分数据输出给Ubuntu Shell 命令. 且 Ubuntu Shell 命令执行的结果也无法直接输入到awk中.

【编辑推荐】

  1. 概括简介Ubuntu shell命令操作
  2. Ubuntu Pattern正则表达式匹配所指定
  3. Ubuntu awk的字段变量内建变量
  4. Ubuntu awk概述内建有pipe的功能
  5. Ubuntu操作系统vim基本使用
责任编辑:佚名 来源: csdn
相关推荐

2016-08-11 09:18:33

awkShellLinux

2013-10-09 11:15:49

Ubuntu应用程序

2020-11-04 18:13:24

DebianUbuntuapt-cache命令

2022-11-23 15:26:25

Ubuntu程序坞

2012-05-08 11:11:43

Linuxcrontab命令

2009-12-31 13:56:16

Ubuntu shel

2017-04-05 13:17:26

LinuxShellvi

2022-11-03 20:38:01

CMD命令Go

2010-05-11 11:34:44

2022-08-04 18:34:18

Ubuntuaptupgrade 命令

2009-08-07 10:31:24

linux命令行模式linux命令行Linux系统

2022-07-25 10:20:39

apt 命令Ubuntu软件包

2023-07-23 19:26:18

Linuxcat 命令

2023-07-04 16:36:03

Linuxcd 命令

2023-01-13 12:37:43

Bashshell花括号

2023-08-12 15:05:26

Linuxcp 命令

2015-08-10 14:42:40

Explain SheShell 命令

2018-10-09 08:30:55

UbuntuLinuxRAR文件

2013-03-12 09:40:56

Ubuntu远程桌面

2021-01-04 05:43:59

LinuxBasename命令
点赞
收藏

51CTO技术栈公众号