2015-04-09 7 views
6

तिथियों के साथ AWK मैं समझता हूँ कि gawk समय mktime और strftime तिथि पर काम करने के लिए केवल 2 कार्य/है।<a href="https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html" rel="nofollow">https://www.gnu.org/software/gawk/manual/html_node/Time-Functions.html</a> से पहले 1970

तो, मैं mktime कि एक लंबे लौटने का उपयोग कर किसी भी तारीख पार्स कर सकते हैं, तो मैं किसी भी गणित सेशन बना सकते हैं, और इसलिए मैं उत्पादन strftime

यह "1970 01 01 00 00 00" के बाद किसी भी तिथि के लिए एक आकर्षण की तरह काम करता साथ वांछित फ़ॉर्मेट कर सकते हैं

अजीब का उपयोग करके, मैं 1 9 70 से पहले तिथियों को कैसे प्रारूपित कर सकता हूं?

$ awk 'BEGIN{t=mktime("1970 01 01 00 00 00"); print t; print strftime("%Y-%m-%d", t) }' 
10800 
1970-01-01 
$ awk 'BEGIN{t=mktime("1960 01 01 00 00 00"); print t; print strftime("%Y-%m-%d", t) }' 
-315608400 
awk: cmd. line:1: (FILENAME=- FNR=1) fatal: strftime: second argument less than 0 or too big for time_t 
+3

आपके पास एक हथौड़ा का उपयोग करने और उन्हें अपने पत्थर के स्लैब में छेड़छाड़ करने के लिए ;-) –

+0

ऐसा लगता है जैसे स्ट्रैटाइम टाइमस्टैम्प (द्वितीय) पैरामीटर के लिए ऋणात्मक मान स्वीकार नहीं करता है, जो represen 1 9 70 01 00 00 00 यूटीसी के बाद से सेकंड की संख्या टीएस। उससे पहले टाइम्स * के बाद * सेकंड की नकारात्मक संख्या होगी। – ReluctantBIOSGuy

+1

आप 'awk' BEGIN {...} ' –

उत्तर

1

इसलिए, यह एक बग है ...

मैं जीएनयू awk उपयोग कर रहा हूँ 4.0.2, स्रोत पर एक litte रूप और ठीक करने के लिए आसान लगता है:

glaudiston:/sources/gawk-4.0.2$ diff builtin.c.orig builtin.c 
1701,1702c1701,1702 
<      if (clock_val < 0) 
<        fatal(_("strftime: second argument less than 0 or too big for time_t")); 
--- 
>      // if (clock_val < 0) 
>      //  fatal(_("strftime: second argument less than 0 or too big for time_t")); 
glaudiston:/sources/gawk-4.0.2$ echo "" | ./gawk '{ts="1969 12 31 23 00 00";format="%Y/%m/%d";tv=mktime(ts);print tv;print strftime(format, tv)}' 
7200 
1969/12/31 
glaudiston:/sources/gawk-4.0.2$ echo "" | ./gawk '{ts="1960 01 01 00 00 00";format="%Y/%m/%d";tv=mktime(ts);print tv;print strftime(format, tv)}' 
-315608400 
1960/01/01 

मेरा उद्देश्य यह काम के लिए, लेकिन मुझे यकीन नहीं है कि यह एक अच्छा विचार था। मैं इसे मंजूरी के लिए गॉक माइलिस्ट को भेजूंगा।

चर्चा शुरू हो गई थीं: https://lists.gnu.org/archive/html/bug-gawk/2015-04/msg00012.html

समाधान अद्यतन:

awk देव टीम बग तय किया है, तो सिर्फ एक नए संस्करण में अपने awk उन्नयन:

https://lists.gnu.org/archive/html/bug-gawk/2015-04/msg00036.html

1

दुर्भाग्यवश, जैसा कि आपने देखा है, गॉक बस इसे सीधे नहीं कर सकता है। gawk manual का कहना है: 0 से 2^31 के माध्यम से

सभी ज्ञात POSIX अनुरूप सिस्टम समर्थन timestamps - 1, जो 2038/01/19 03:14:07 यूटीसी के माध्यम से कई बार प्रतिनिधित्व करने के लिए पर्याप्त है। कई प्रणालियां टाइमस्टैम्प की एक विस्तृत श्रृंखला का समर्थन करती हैं, जिसमें नकारात्मक टाइमस्टैम्प भी शामिल हैं जो युग से पहले समय का प्रतिनिधित्व करते हैं।

मैनुअल यह नहीं कहता कि strftime() क्या बाहर की तारीख को दिया गया है।

लेकिन फिर भी अपने सिस्टम है, जो 1970 मैं विचार यह एक बग होने के लिए पहले दिनांक को संभाल नहीं सकता समझदारी से नकारात्मक time_t मूल्यों के लिए व्यवहार करते हैं करता है, gawk के strftime() समारोह उन्हें समर्थन नहीं करता है (हालांकि mktime() करता है), और इतने पर गॉक में

(मेरी सलाह Awk के बजाय पर्ल का उपयोग करने के होगा, लेकिन इस सवाल का जवाब देने के लिए कहा नहीं है।)

सिद्धांत रूप में, आप awk में strftime() की तरह एक समारोह को फिर से लागू करने से पहिया बदलने सकता है । लेकिन यह अधिक होगा।

यदि आपके सिस्टम में जीएनयू कोर्यूटिल्स date कमांड काम कर रहा है, तो आप इसे gawk से आवेदक कर सकते हैं।

$ cat 1960.awk 
#!/usr/bin/awk -f 

BEGIN { 
    timestamp = mktime("1960 00 00 00 00 00") 
    print "mktime() returned " timestamp 

    if (0) { 
     # This doesn't work 
     s = strftime("%Y-%m-%d %H:%M:%S", timestamp) 
     print "strftime() returned ", s 
    } 
    else { 
     # This works 
     "date '+%Y-%m-%d %H:%M:%S' -d @" timestamp | getline t 
     print "The date command printed \"" t "\"" 
    } 
} 
$ ./1960.awk 
mktime() returned -318355200 
The date command printed "1959-11-30 00:00:00" 
$ 

(। मैं उद्धरण और बैकस्लैश एक सुरक्षा प्रॉम्प्ट से एक एक लाइनर के रूप में यह करने के लिए की जरूरत के अनुक्रम पता लगाना पर छोड़ दिया)

यह शायद: जनवरी 1, 1960 के अपने उदाहरण का उपयोग यदि आपके पास एक बड़ा मौजूदा अजीब प्रोग्राम है और आपको इसे एक सुविधा जोड़ने की आवश्यकता है तो यह समझ में आता है। लेकिन अगर आप इसे अजीब में करने से फंस नहीं गए हैं, तो आप कुछ और इस्तेमाल करने पर विचार कर सकते हैं; जो भी आप पूरा करने की कोशिश कर रहे हैं उसके लिए अजीब उपकरण नहीं हो सकता है।

या, यदि आप वास्तव में महत्वाकांक्षी हैं, तो आप इस मामले को सही तरीके से संभालने के लिए gawk स्रोतों को संशोधित कर सकते हैं।

+0

'mktime' समस्या नहीं है, यह ठीक काम कर रहा है। समस्या बार-बार प्रतीत होती है और एक तिथि का उपयोग एक विकल्प नहीं है क्योंकि बहुत धीमी और बहुत महंगा है। मैं देखता हूं कि यह कैसे perl में है। – ton

+0

@ton: आप सही हैं। मैंने अपना जवाब अपडेट कर लिया है (और एक और संभावित विकल्प सुझाया है: 'गॉक' स्वयं को ठीक करना)। –

संबंधित मुद्दे