จะค้นหาความแตกต่างระหว่างการประทับเวลาสองครั้งได้ถึงมิลลิวินาทีได้อย่างไร


10

ฉันใหม่สำหรับการเขียนสคริปต์เชลล์ หัวใจของสคริปต์ของฉันคือการหาความแตกต่างระหว่างการประทับเวลาสองครั้งจนถึงมิลลิวินาที กับฉันฉันมีไฟล์ที่มีเนื้อหาของการประทับเวลาเท่านั้นเช่น

2012-09-13 15:00:29,290 2012-09-13 15:00:29,297
2012-09-13 15:00:29,428 2012-09-13 15:00:29,447

เช่นนี้ฉันมีบันทึกประมาณ 30k ซึ่งฉันไม่ควรประสบปัญหาด้านประสิทธิภาพเมื่อรันสคริปต์ ปัจจัยหลายอย่างเช่นปีอธิกสุรทินเดือนที่มี 31 วันและอื่น ๆ เข้ามาในรูปภาพเมื่อฉันพยายามเขียนสคริปต์สำหรับเรื่องนี้

ใครสามารถช่วยฉันในเรื่องนี้ได้ไหม


1
DST เข้ามาในรูปภาพหรือไม่ เผ่นวินาที กฎ DST คืออะไร พวกเขาเปลี่ยนแปลงตลอดเวลาในประเทศของคุณหรือไม่ คุณต้องจัดการกับวันที่ก่อนปี 1970 หรือก่อนที่จะเปลี่ยนเป็นปฏิทินเกรโกเรียน
Stéphane Chazelas

คำตอบ:


13

ไม่จำเป็นต้องทำการแยกวิเคราะห์ที่ซับซ้อนจะทำเวทย์มนตร์สำหรับคุณด้วยความช่วยเหลือจากเพื่อนของเขา :

#!/bin/bash
while read d1_1 d1_2 d2_1 d2_2; do
  secdiff=$((
    $(date -d "$d2_1 $d2_2" +%s) - $(date -d "$d1_1 $d1_2" +%s)
  ))
  nanosecdiff=$((
    $(date -d "$d2_1 $d2_2" +%N) - $(date -d "$d1_1 $d1_2" +%N)
  ))
  printf "%s %s - %s %s = %d milliseconds\n" $d2_1 $d2_2 $d1_1 $d1_2 $((
    (secdiff * 1000) + (nanosecdiff / 1000000)
  ))
done < YOUR_FILE.txt

เอาท์พุท

2012-09-13 15:00:29,297 - 2012-09-13 15:00:29,290 = 7 milliseconds
2012-09-13 15:00:29,447 - 2012-09-13 15:00:29,428 = 19 milliseconds

ดู man date

บันทึก

  • date -d มีประโยชน์มากมันแปลงการประทับเวลา
  • %sคือเวลาของยุค (วินาทีตั้งแต่ 01-01-1970)
  • %Nคือนาโนวินาที
  • $(( ))และใช้(( ))สำหรับbashเลขคณิตดูhttp://mywiki.wooledge.org/ArithmeticExpression
  • $( ) หมายถึง command substitution

สิ่งนี้เหมาะกับความต้องการของคุณเช่นกันหรือไม่?


1
แก้ไขข้อผิดพลาดทางคณิตศาสตร์ (เชื่อมต่อวินาทีและนาโนวินาที) ตอนนี้ฉันคำนวณวินาทีก่อนหน้านี้ (OP ไม่ได้ถาม แต่เพื่อความสมบูรณ์และความทนทานในการใช้ซ้ำ)
Gilles Quenot

0

ภาษาสคริปต์เช่น Perl, Python หรือ Ruby จะรวดเร็วและต้องใช้ความพยายามเล็กน้อย ตัวอย่างเช่นด้วย Perl และDate :: Parse :

perl -MDate::Parse -l -ne 's/,/./g; split; print str2time("$_[2] $_[3]") - str2time("$_[0] $_[1]")'

(สำหรับแต่ละบรรทัดแทนที่,โดย.แยกบรรทัดลงในคำ$_[0]ผ่าน$_[3]แยกวันที่เกิดขึ้นจากสองครั้งแรกและสองคำต่อไปและพิมพ์ที่แตกต่างกัน.)


"ความพยายามน้อย" เป็นญาติค่อนข้าง แน่นอนถ้าคุณเป็นโปรแกรมเมอร์ X และรู้เกี่ยวกับห้องสมุด Y มันเป็นของแน่นอน นั่นเป็นวิธีที่เคยเป็น ที่จริงฉันประหลาดใจที่โปรแกรมเมอร์ Python ยังไม่ได้กระโดดเข้ามาที่นี่ ฉันคิดว่ามันเป็นเรื่องของเวลา ... : - \
Mike S

นั่นเป็นเหตุผลที่ผู้คนให้วิธีการแก้ปัญหาที่นี่ ด้วยวิธีนี้คุณไม่จำเป็นต้องเป็นโปรแกรมเมอร์ X หรือรู้เกี่ยวกับห้องสมุด Y และคุณยังคงได้รับประโยชน์จาก "ความพยายามเพียงเล็กน้อย" ในการมีหนึ่งบรรทัดในสคริปต์ของคุณและไม่ใช่ 10
CherryDT

0

ฉันเพิ่งเจอโพสต์นี้มี - อย่างน้อยวันนี้ - dateโซลูชั่นที่ใช้ง่าย การใช้เฟรมเวิร์กในคำตอบของ @Gilles Quenot (จะเขียนความคิดเห็นไปยังผู้ดูแลของเขา แต่ชื่อเสียงไม่เพียงพอ):

while read d1_1 d1_2 d2_1 d2_2
do
    date -d "$d2_1 $d2_2 $(date -d "$d1_1 $d1_2" +%s.%N) seconds ago" +%s.%N
done << END
2012-09-13 15:00:29,290 2012-09-13 15:00:29,297
END

ผลลัพธ์:

$ ./time_elapsed.sh 
0.007000000

การใช้%3Nแทน%Nจะตัดทอนผลลัพธ์เป็นมิลลิวินาที

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.