หากฉันมีวันที่ด้านล่างสองวัน:
2015-09-12,2015-08-13
และฉันต้องการได้จำนวนวันระหว่างพวกเขาฉันจะใช้รหัสด้านล่าง:
awk -F'[-,]' '{print 360*($4-$1)+30*($5-$2)+($6-$3)}'
ผลลัพธ์สำหรับรหัสนี้จะเป็น-29
จริงในขณะที่ความแตกต่างคือ29
หากฉันมีวันที่ด้านล่างสองวัน:
2015-09-12,2015-08-13
และฉันต้องการได้จำนวนวันระหว่างพวกเขาฉันจะใช้รหัสด้านล่าง:
awk -F'[-,]' '{print 360*($4-$1)+30*($5-$2)+($6-$3)}'
ผลลัพธ์สำหรับรหัสนี้จะเป็น-29
จริงในขณะที่ความแตกต่างคือ29
คำตอบ:
คุณสามารถกำหนดฟังก์ชั่นในรูป awk
แบบ:
awk -F'[-,]' '
function abs(v) {return v < 0 ? -v : v}
{print abs(360*($4-$1)+30*($5-$2)+($6-$3))}'
เคล็ดลับทั่วไปสำหรับสถานการณ์แบบนี้คือการใช้สแควร์รูทของสแควร์:
awk -F'[-,]' '{print sqrt((360*($4-$1)+30*($5-$2)+($6-$3))^2)}'
sqrt(x^2)
นั่นเป็นเหตุผลที่มันเป็น
อีกวิธีหนึ่ง:
awk -F'[-,]' '{d=360*($4-$1)+30*($5-$2)+($6-$3);print (d>0)?d:-d}'
สมมติว่าคุณใช้ GNU awk
แล้วmktime
ฟังก์ชั่นขี้ขลาดจะเป็นประโยชน์ที่นี่
awk -F, '{ gsub(/-/," ",$0);a=(mktime($2 " 23 59 59")-mktime($1 " 00 00 00"))/86400;print a*(a<0?-1:1)}' file.txt
29
จนถึงล่าช้า แต่นี่เป็นวิธีการแก้ปัญหาโดยใช้date
คำสั่งGNU ซึ่งไม่ได้อยู่บนพื้นฐาน 30 วันในแต่ละเดือนซึ่งคำตอบทั้งหมดที่โพสต์ไว้ข้างต้นนั้นถือว่าเป็นคำตอบของสตีฟ
awk -F, '{cmd="printf \"%d\n\" $((($(date -d"$1" +%s)-$(date -d"$2" +%s))/86400))";
cmd|getline $0; $0*=($0<0?-1:1); close(cmd)}1' infile
สำหรับอินพุตด้านล่าง:
2015-09-12,2015-08-13
2017-02-12,2017-03-12
ผลลัพธ์คือ:
30
28
sqrt(x^2)
แต่sqrt(x)^2
สามารถแนะนำข้อผิดพลาดเล็ก ๆ ที่อาจทำให้ประหลาดใจ สำหรับ busyboxawk
จะต้องมีการสร้างโดยเปิดใช้งานการสนับสนุนทางคณิตศาสตร์ (ไม่ใช่ค่าเริ่มต้นในแพ็คเกจ Debian เป็นต้น)