awk中pipe的shell命令調用與close()

    某公司其員工到勤時間表如下, 取名為 arr.dat, 文件中第一欄為員工代號, 第二欄為到達時間. 本示例中將使用該文件為數據示例文件,

1034 7:26

1025 7:27

1101 7:32

1006 7:45

1012 7:46

1028 7:49

1051 7:51

1029 7:57

1042 7:59

1008 8:01

1052 8:05

1005 8:12

要求: 

(1) 將數據arr.dat按員工ID排序, 并在表頭附加上執行時的日期

(2) 在arr.dat之前增加一行數據抬頭如下" ID Number Arrival Time"

(3) 若八點為上班時間, 請加標注"*" 與遲到時間之后, 并計算平均上班時間.

(4) 將arr.dat重新輸出到today.art文件中

答案與解析:

建立文件名為reformat.awk的awk文件, 內容如下

BEGIN {
    FS="[ \t:]"  #此處重新定義輸入字段分隔符, 默認值為空白, 此處使用 [ \t:]+ (為正則表達式) 表示 \
  使用 "空吧, tab或 : " 做組成的字符創做分隔符, + 表示可以出現一次或一次以上;
    "date" | getline  #此處為在awk中調用shell的命令, 需要使用 ""括主, 并且需要使用 pipe( | ) 傳遞給 getline(awk的內建函數, 用于調用shell命令);
    print " Today is ",$2, $3  > "today.art"   #輸出重定向, 將輸出重定向到today.art中, 并創建文件
    print "====================================" >> "today.art" # 使用>> 而非 > , >> 是在原有文件后面追加, > 是清空文件, 故使用 >>
    print " ID Number Arrival Time" >> "today.art"
    close("today.art")   #此處稍后解釋
}
{
    arrival = HM_to_M( $2, $3 )  # 此處為awk中的自定義函數, 在后邊定義, 是計算遲到時間, 將時間轉換成分鐘
    printf(" %s %s:%s %s\n", $1, $2, $3, arrival > 480 ? "*" : " ") | " sort -k 1 >> today.art" 
    # 通過重新定義FS, 將源文件 分割成3 段, 第2, 3段表示的時間, 其中arriva > 480 ? "*" : " "  為判斷是否遲到, 遲到的后邊增加標記 * , 480 為8點的分鐘數
    # 通過 | 將命令暫存到 | 上, 并且不會執行輸出, 也不會執行sort命令, 在awk全部執行完畢后, 才會執行
    total += arrival # 計算總的時間, 為了計算后邊的平均到達時間
}
END {
    close("today.art")
    close("sort -k 1 >> today.art") 
    #awk中的close()指令, 語法有兩種, close( filename ) 和close( 置于pipe之前的command ). 指令close( "sort -k 1 >> today.art" ) 
    #其意思是 close 程序中置于"sort -k 1 >> today.art "之前的pipe, 并立即調用shell來執行sort命令
    printf(" Average Arrival Time : %d:%d\n", arrival/NR/60, (arrival/NR)%60 ) >> "today.art"  #awk中"today.art"若表示文件名, 必須使用"' 括起來, 若不適用, 會被當做變量
    # 計算平均到達時間, NR是內建變量, 表示讀入文件的總行數, arrival/NR/60 表示取整得到小時, (arrival/NR)%60 取余數得到分鐘數;
}
function HM_to_M( hour, min ) {
    return hour*60 + min
}
# 自定義函數, 計算員工達到的分鐘數, 與8點的分鐘數480進行比較

 

最后通過 awk -f reformat.awk arr.dat 得到文件 today.art, 內容如下

 Today is  11月 08日

===================================

 ID Number Arrival Time

 1005 8:12 *

 1006 7:45  

 1008 8:01 *

 1012 7:46  

 1025 7:27  

 1028 7:49  

 1029 7:57  

 1034 7:26  

 1042 7:59  

 1051 7:51  

 1052 8:05 *

 1101 7:32  

原創文章,作者:black_fish,如若轉載,請注明出處:http://www.www58058.com/58585

(0)
black_fishblack_fish
上一篇 2016-11-10
下一篇 2016-11-11

相關推薦

  • 系統啟動和內核管理-1

    1、Linux 組成 kernel: 進程管理、內存管理、網絡管理、驅動程序、文件系統、安全功能等等 rootfs: 程序和glibc 內核設計流派: 單內核(monolithic kernel)-Linux-把所有功能集成于同一個程序 微內核(micro kernel)-Windows, Solaris-每種功能使用一個單獨子系統實現 1)、Linux內核…

    Linux干貨 2016-09-13
  • Linux命令的別名與管道命令的詳解

    Linux中命令的別名與管道命令的詳解 命令別名 在使用和維護liunx時,將會使用大量的命令,而一些命令加上參數時輸入比較繁瑣,此時我們可以定義一個別名來代替繁瑣的命令。 系統定義的別名 可以輸入 alias 命令查看系統中已經定義好的命令的別名; [root@localhost ~]# alias alias cp=’cp -i’ alias egrep…

    Linux干貨 2018-03-03
  • 文件元數據信息的含義、查看方法,和文件時間戳信息的修改方法

    文件數據分成兩類 元數據,英文叫metadata,是數據的屬性; 數據,英文叫data,是數據本身; 使用stat命令查看元數據信息 [0][root@localhost mylinux]# stat /etc/passwd File: ‘/etc/passwd’ Size: 889 Blocks: 8 IO Block: 4096 regular file…

    Linux干貨 2018-03-01
  • Mariadb數據庫復制系列(五):基于SSL的復制

       實驗五:基于SSL的主從復制功能的實現 在mysql服務器之間復制數據,默認情況下都是基于明文的,在有些場景中,明文傳輸會造成嚴重的數據安全隱患,因此,需要對mysql服務器之間的復制時的傳輸進行加密,傳輸加密方式可以基于SSL的會話進行 1、實驗環境 2、私有CA的搭建 3、在主節點node72上生成證書簽署請求、發送到私有CA服務器 4、在從節點n…

    Linux干貨 2016-11-24
  • 【福利貼-招聘】- python運維開發工程師

    職位描述  崗位職責: 1、負責公司CMDB的建設,包括資產管理、dns、工單系統、ngnix自動化、監控等的開發 2、幫助運維團隊和業務團隊提高自動化效率 3、維護和開發持續化集成環境; 4、負責公司運維系統的規劃、選型、部署上線和日常維護管理工作; 5、負責CMDB團隊的建設、管理和人才培養機制…

    Linux干貨 2015-04-03
  • 網絡管理2

    六、配置網絡     跨網絡通信:路由     路由分類:         主機路由         網絡路由 &nbs…

    Linux干貨 2016-09-09
欧美性久久久久