[英]Awk printing out smallest and highest number, in a time format
我是linux / bash shell的新手,我真的無法從文本文件中的特定列打印兩個值(最高和最低)。 該文件的格式如下:
Geoff Audi 2:22:35.227
Bob Mercedes 1:24:22.338
Derek Jaguar 1:19:77.693
Dave Ferrari 1:08:22.921
正如您所看到的,最后一列是時間,我正在嘗試使用awk打印出列中的最高和最低時間。 我真的很難過,我試過了:
awk '{print sort -n < $NF}' timings.txt
然而,這甚至沒有任何排序,我剛收到的輸出:
1
0
1
0
...
一遍又一遍地重復,它持續了更長時間,但是當你在第一次迭代之后得到點時我不想要它的大量線。
我想要的輸出是:
Min: 1:08:22.921
Max: 2:22:35.227
問題澄清 后 :如果時間字段總是具有在同一個地方一個相同的位數,例如h:mm:ss.ss
,溶液可以顯着地簡化。 也就是說,我們不需要將時間轉換為秒來進行比較,我們可以進行簡單的字符串/詞典編纂比較:
$ awk 'NR==1 {m=M=$3} {$3<m&&m=$3; $3>M&&M=$3} END {printf("min: %s\nmax: %s",m,M)}' file
min: 1:08:22.921
max: 2:22:35.227
邏輯與下面的(上一個)腳本中的邏輯相同,只是使用更簡單的基於字符串的比較來排序值(確定最小值/最大值)。 我們可以做到這一點,因為我們知道所有的時間都符合相同的格式,如果a < b
(例如"1:22:33" < "1:23:00"
)我們知道a
比b
更“小”。 (如果值的格式不一致,那么單獨使用詞典比較,我們無法對它們進行排序,例如"12:00:00" < "3:00:00"
。)
因此,在第一個值讀取(第一個記錄, NR==1
)時,我們將初始最小/最大值設置為讀取的時間(在第3個字段中)。 對於每個記錄,我們測試當前值是否小於當前min,如果是,我們設置新的min。 同樣的最大值。 if
要使表達式更短,我們使用短路( $3<m && m=$3
相當於if ($3<m) m=$3
)。 在END
我們只需打印結果。
這是一個通用的awk
解決方案 ,接受每個記錄的小時/分鍾/秒的可變位數的時間字符串:
$ awk '{split($3,t,":"); s=t[3]+60*(t[2]+60*t[1]); if (s<min||NR==1) {min=s;min_t=$3}; if (s>max||NR==1) {max=s;max_t=$3}} END{print "min:",min_t; print "max:",max_t}' file
min: 1:22:35.227
max: 10:22:35.228
或者,以更易讀的形式:
#!/usr/bin/awk -f
{
split($3, t, ":")
s = t[3] + 60 * (t[2] + 60 * t[1])
if (s < min || NR == 1) {
min = s
min_t = $3
}
if (s > max || NR == 1) {
max = s
max_t = $3
}
}
END {
print "min:", min_t
print "max:", max_t
}
對於每一行,我們將時間分量(小時,分鍾,秒)從第三個字段轉換為秒,我們稍后可以將其作為數字進行比較。 在迭代時,我們跟蹤當前的最小值和最大值,並在END
打印它們。 min和max的初始值取自第一行( NR==1
)。
鑒於您的陳述時間字段實際上是一個持續時間而小時組件始終是一個數字,這就是您所需要的:
$ awk 'NR==1{min=max=$3} {min=(min<$3?min:$3); max=(max>$3?max:$3)} END{print "Min:", min ORS "Max:", max}' file
Min: 1:08:22.921
Max: 2:22:35.227
你不想在awk中運行sort(即使使用正確的語法)。
試試這個:
sed 1d timings.txt | sort -k3,3n | sed -n '1p; $p'
哪里
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.