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 20:07
下一篇 2016-11-11 08:41

相關推薦

  • 關于Linux文件系統的的簡單理解和認識-20160730

    關于Linux文件系統的的簡單理解和認識 關于文件系統的運作,這與操作系統帶的檔案數據有關。例如Linux操作系統的檔案權限(rwx)與文件屬性(擁有者,群組,時間參數等)。文件系統通常會將這兩部分的數據分別存放在不同的區塊,權限與屬性放置到inode中,至于實際數據則放置到date block區塊中,另外,還有一個超級塊區(super block)會記錄整…

    Linux干貨 2016-08-04
  • Linux終端類型

      終端是一種字符型設備,它有多種類型,通常使用tty來簡稱各種類型的終端設備。   在Linux系統的設備特殊文件目錄/dev/下,終端特殊設備文件一般有以下幾種:   1、串行端口終端 /dev/ttySn     串行端口終端是使用計算機串行端口連接的終端設備。計算機把每個串行端口都看作是一個…

    Linux干貨 2016-10-14
  • Ansible的常用模塊

    command模塊: 目的:在指定節點上運行hostname命令 命令:ansible 192.168.1.16 -m command ?‘hostname’copy模塊:目的:把主控端/root目錄下的a.sh文件拷貝到到指定節點上 命令:ansible 192.168.1.16 -m copy -a ‘src=/roo…

    Linux干貨 2017-10-31
  • shell腳本之批量添加用戶

        沒錯,這是一個簡單的腳本,不寫不知道,寫了才發現自己多垃圾。     我是一名普通的公司網絡管理,接觸linux不長,一直理想都是和馬哥學習linux,可惜因為拖家帶口的原因,沒辦法交學費和馬哥學習,心里小小遺憾吧。每天看著馬哥的文章以及百度搜索的視頻文章學習,感覺自己學…

    Linux干貨 2016-07-07
  • 8.1作業

    8月1日作業 創建testuser uid 1234,主組:bin,輔助組:root,ftp,shell:/bin/csh home:/testdir/testuser [root@localhost ~]# useradd -u 1234 -g bin -G root,ftp&…

    Linux干貨 2016-08-04
  • 顯示歷史命令時間

        歷史命令中默認是不顯示時間的,如果我們想要在使用history命令時顯示時間可以通過設置環境變量來實現。     HISTTIMEFORMAT變量的具體參數與date命令中的類似,可以參數date命令的對日期時間格式時行修改。    &nbs…

    Linux干貨 2015-05-02
欧美性久久久久