क्या स्टैम्प के लिए टाइमस्टैम्प को रोकने के लिए एक यूनिक्स उपयोगिता है?


168

मैंने पायथन में इसके लिए एक त्वरित छोटी स्क्रिप्ट लिखना समाप्त कर दिया, लेकिन मैं सोच रहा था कि क्या कोई उपयोगिता थी जो आप पाठ को फीड कर सकते थे जिसमें प्रत्येक पंक्ति को कुछ पाठ के साथ प्रस्तुत करना होगा - मेरे विशिष्ट मामले में, टाइमस्टैम्प। आदर्श रूप से, उपयोग कुछ इस तरह होगा:

cat somefile.txt | prepend-timestamp

(इससे पहले कि आप सीड का जवाब दें, मैंने यह कोशिश की:

cat somefile.txt | sed "s/^/`date`/"

लेकिन यह कि केवल एक बार sed निष्पादित होने पर दिनांक कमांड का मूल्यांकन करता है, इसलिए उसी टाइमस्टैम्प को गलत तरीके से प्रत्येक पंक्ति में रखा गया है।)


क्या cat somefile.txtथोड़ा "भ्रामक" है? मुझे उम्मीद है कि यह "एक ही बार में" होगा और एक एकल टाइमस्टैम्प होगा। यह एक बेहतर परीक्षण कार्यक्रम नहीं होगा (echo a; sleep 1; echo b; sleep 3; echo c; sleep 2):?
सिरो सेंटिल्ली 郝海东 冠状 iro 法轮功

जवाबों:


185

प्रयोग करके देख सकते हैं awk:

<command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; fflush(); }'

आपको यह सुनिश्चित करने की आवश्यकता हो सकती है कि <command>लाइन बफ़र आउटपुट उत्पन्न करता है, अर्थात यह प्रत्येक लाइन के बाद अपने आउटपुट स्ट्रीम को फ्लश करता है; टाइमस्टैम्प awkजोड़ता वह समय होगा जब लाइन का अंत उसके इनपुट पाइप पर दिखाई देता है।

यदि awk त्रुटियों को दिखाता है, तो gawkइसके बजाय प्रयास करें ।


31
मेरे सिस्टम पर 'जाग' ही बफरिंग थी। (यह लॉग फ़ाइलों के लिए समस्याग्रस्त हो सकता है)। मैंने इसका उपयोग करके इसे ठीक किया: awk '{प्रिंट स्ट्रैफ़ाइम ("% Y-% m-% dT% H:% M:% S"), $ 0; fflush (); } '
user47741

19
strftime () एक GNU awk एक्सटेंशन प्रतीत होता है, इसलिए यदि आप Mac OS पर हैं, उदाहरण के लिए, awk के बजाय gawk का उपयोग करें।
जो शॉ

यह मुझे विस्मित करने के लिए बंद नहीं करता है कि कितना शक्तिशाली बैश है। मुझे नहीं लगता था कि इस जटिल कार्य के लिए इतना आसान समाधान होगा।
10

2
ओएस एक्स उपयोगकर्ताओं के लिए, आपको gawkइसके बजाय इंस्टॉल और उपयोग करना होगा awk। अगर आपके पास MacPorts है:sudo port install gawk
मैट विलियमसन

5
@teh_senaus जहाँ तक मुझे पता है, awkकी strftime()मिलीसेकंड सटीक नहीं है। हालाँकि आप dateकमांड का उपयोग कर सकते हैं । मूल रूप से आप सिर्फ नैनोसेकंड को तीन अक्षरों में ट्रिम करते हैं। यह इस तरह दिखेगा COMMAND | while read -r line; do echo "$(date '+%Y-%m-%d %T.%3N') $line"; done:। ध्यान दें कि आप% H:% M:% S को% T के साथ संक्षिप्त कर सकते हैं। यदि आप अभी भी awkकिसी कारण से उपयोग करना चाहते हैं , तो आप निम्न कार्य कर सकते हैं:COMMAND | awk '{ "date +%Y-%m-%d\\ %T.%3N" | getline timestamp; print timestamp, $0; fflush(); }'
सिक्स

190

tsसे moreutils इनपुट के हर लाइन के लिए एक टाइमस्टैम्प पहले जोड़ें होगा आप इसे दे। आप स्ट्रैपटाइम का उपयोग करके भी इसे प्रारूपित कर सकते हैं।

$ echo 'foo bar baz' | ts
Mar 21 18:07:28 foo bar baz
$ echo 'blah blah blah' | ts '%F %T'
2012-03-21 18:07:30 blah blah blah
$ 

इसे स्थापित करने के लिए:

sudo apt-get install moreutils

2
एक ही समय bad command 2>&1 | tsमें Jan 29 19:58:31 -bash: bad: command not found
स्टैडर

मैं समय प्रारूप का उपयोग करना चाहता हूं 2014 Mar 21 18:07:28। मैं इसे कैसे लूं?
becko

@becko - मैनुअल पृष्ठ के अनुसार , strftimeतर्क के रूप में एक प्रारूप स्ट्रिंग दें : [.. command ..] | ts '%Y %b %d %T'उदाहरण के लिए।
टोबे स्पाइट

2
ओएस एक्स के लिए, brew install moreutils। UTC को आउटपुट करने के लिए, आप स्थानीय स्तर पर TZ सेट कर सकते हैं, जैसेls -l |TZ=UTC ts '%Y-%m-%dT%H:%M:%SZ'
kamakaze

1
@ डोरियन यह है क्योंकि रूबी आउटपुट बफ़र कर रहा है; यदि आप सोने से पहले बफर को फ्लश करते हैं तो यह पर्याप्त रूप से काम करता है:ruby -e "puts 1; STDOUT.flush; sleep 1; puts 2; STDOUT.flush; sleep 2; puts 3" | ts '%F %T'
umläute

45

एनोटेट , उस लिंक के माध्यम से या annotate-outputडेबियन devscriptsपैकेज में उपलब्ध है।

$ echo -e "a\nb\nc" > lines
$ annotate-output cat lines
17:00:47 I: Started cat lines
17:00:47 O: a
17:00:47 O: b
17:00:47 O: c
17:00:47 I: Finished with exitcode 0

1
यह एक महान समाधान है, लेकिन पाइप्ड आउटपुट या सबस्लेम्ड आउटपुट के साथ काम नहीं करेगा। यह केवल एक प्रोग्राम या स्क्रिप्ट के लिए आउटपुट को पुन: स्वरूपित करेगा जिसे आप इसे एक तर्क के रूप में देते हैं।
स्लेम

1
एनोटेट-आउटपुट अच्छी तरह से काम करता है और उपयोग में आसान है, लेकिन वास्तव में धीमा है।
पॉल ब्रानन

31

दिए गए उत्तरों को सरलतम रूप से वितरित करना:

unbuffer $COMMAND | ts

उबंटू पर, वे उम्मीद-देव और मोरटिल्स पैकेज से आते हैं।

sudo apt-get install expect-dev moreutils

1
यह expectनहीं है expect-dev, लेकिन बाद वाला पूर्व में खींचता है इसलिए यह काम करता है। (उबंटू 14.10, मुझे आश्चर्य है कि अगर बाइनरी को किसी बिंदु पर एक अलग पैकेज में स्थानांतरित किया गया था।)
मारियस गेदमिनस

Ubuntu 14.04 LTS के लिए, यह अभी भी हैexpect-dev
Willem

2
यदि आप unbuffer $COMMAND | ts -s %.s-s%.s
मिलिसेकंड

24

इस बारे में कैसा है?

cat somefile.txt | perl -pne 'print scalar(localtime()), " ";'

लाइव टाइमस्टैम्प प्राप्त करने की अपनी इच्छा से देखते हुए, शायद आप लॉग फाइल या कुछ और पर लाइव अपडेट करना चाहते हैं? शायद

tail -f /path/to/log | perl -pne 'print scalar(localtime()), " ";' > /path/to/log-with-timestamps

4
यह पर्ल उदाहरण मेरे लिए विशेष रूप से उपयोगी था क्योंकि मैं एक ubuntu तैनाती पर एक उपयोगकर्ता के रूप में काम कर रहा था, जो जाहिरा तौर पर aw gawk ’के बजाय of mawk’ का उपयोग करता है - और इसमें स्ट्रैप्टम फ़ंक्शन नहीं होता है। धन्यवाद!
opello

4
+1 यह एक डिफ़ॉल्ट उबंटू इंस्टॉल पर काम करता है। मैं tail -f /path/to/log | perl -pne 'use POSIX qw(strftime); print strftime "%Y-%m-%dT%H:%M:%SZ ", gmtime();'एक साधारण संस्करण पैदावार wacko के बजाय एक ISO8601 / RFC3339 शैली दिनांक प्राप्त करता था।
natevw

1
यदि आप टाइमस्टैम्प्ड लॉग आउटपुट को देखने में सक्षम होना चाहते हैं, तो यह BEGIN { $|++; }प्रिंट स्टेटमेंट से पहले जोड़ने के लिए सहायक हो सकता है ताकि पर्ल प्रत्येक लाइन के साथ अपने आउटपुट को फ्लश कर सके।

2
आप पर्ल स्क्रिप्ट को आगे सिर्फ छोटा कर सकते हैं ls | perl -pne 'print localtime." "'। स्केलर रूपांतरण, स्ट्रिंग के संघनन के कारण होता है।
राहुल

आप दोनों -pऔर -nविकल्पों का उपयोग क्यों करते हैं ? ऐसा लगता है कि -nअनावश्यक है यदि आपके द्वारा निर्दिष्ट -p
क्यूब्रेनिक

19

बस इसे वहां से बाहर फेंकना है: डेमोनटूल में उपयोगिताओं की एक जोड़ी होती है जिसे ताई 64 एन और टिएननलोक कहा जाता है जो लॉग संदेश भेजने के लिए टाइमस्टैम्प बनाने के लिए बनाई गई हैं।

उदाहरण:

cat file | tai64n | tai64nlocal

18

किरोन का जवाब अब तक का सबसे अच्छा है। यदि आपको समस्या है क्योंकि पहला प्रोग्राम इसकी बफरिंग कर रहा है तो आप अनबफर प्रोग्राम का उपयोग कर सकते हैं:

unbuffer <command> | awk '{ print strftime("%Y-%m-%d %H:%M:%S"), $0; }'

यह अधिकांश लिनक्स सिस्टम पर डिफ़ॉल्ट रूप से स्थापित है। यदि आपको इसे स्वयं बनाने की आवश्यकता है तो यह अपेक्षित पैकेज का हिस्सा है

http://expect.nist.gov


ध्यान दें कि मैंने पाया है कि 'अनबफ़र' कभी-कभी बुलाए गए प्रोग्राम का रिटर्न रिजल्ट छुपा देता है - इसलिए जेनकींस या अन्य चीजों में यह उपयोगी नहीं है जो रिटर्न स्टेटस पर निर्भर करते हैं
ऑस्करपर्सन

10

मानक इनपुट से एक बार में एक पंक्ति को पढ़ने के लिए रीड (1) कमांड का उपयोग करें, फिर दिनांक (1) का उपयोग करके अपने चयन के प्रारूप में दिनांक के साथ पहले से तैयार लाइन का उत्पादन करें।

$ cat timestamp
#!/bin/sh
while read line
do
  echo `date` $line
done
$ cat somefile.txt | ./timestamp

2
एक बिट हैवीवेट के रूप में यह प्रति पंक्ति एक नई प्रक्रिया की तलाश करता है, लेकिन यह काम करता है!
जो शा

3

मैं एक यूनिक्स लड़का नहीं हूं, लेकिन मुझे लगता है कि आप उपयोग कर सकते हैं

gawk '{print strftime("%d/%m/%y",systime()) $0 }' < somefile.txt

3
#! /bin/sh
unbuffer "$@" | perl -e '
use Time::HiRes (gettimeofday);
while(<>) {
        ($s,$ms) = gettimeofday();
        print $s . "." . $ms . " " . $_;
}'

2

यहाँ मेरा awk solution है (C: \ bin डायरेक्टरी में MKS टूल्स के साथ विंडोज / XP सिस्टम से)। इसे मिमी / dd hh: mm में वर्तमान तिथि और समय को जोड़ने के लिए डिज़ाइन किया गया है, प्रत्येक पंक्ति की शुरुआत में मिमी उस प्रणाली से टाइमस्टैम्प प्राप्त करता है जैसा कि प्रत्येक पंक्ति पढ़ी जाती है। आप निश्चित रूप से टाइमस्टैम्प लाने के लिए BEGIN पैटर्न का उपयोग कर सकते हैं और उस टाइमस्टैम्प को प्रत्येक रिकॉर्ड (सभी समान) में जोड़ सकते हैं। मैंने एक लॉग फ़ाइल को टैग करने के लिए ऐसा किया था जो उस समय टाइमस्टैम्प के साथ उत्पन्न होने के लिए उत्पन्न हो रही थी जब लॉग संदेश उत्पन्न हुआ था।

/"pattern"/ "C\:\\\\bin\\\\date '+%m/%d %R'" | getline timestamp;
print timestamp, $0;

जहां "पैटर्न" इनपुट लाइन में मिलान करने के लिए एक स्ट्रिंग या रेगेक्स (उद्धरण के बिना) है, और यदि आप सभी इनपुट लाइनों से मेल खाना चाहते हैं तो वैकल्पिक है।

यह लिनक्स / यूनिक्स प्रणालियों पर भी काम करना चाहिए, बस लाइन से बाहर निकल कर C \: \\ bin \\ से छुटकारा पाना चाहिए

             "date '+%m/%d %R'" | getline timestamp;

यह, निश्चित रूप से, मानता है कि कमांड "तिथि" आपको विशिष्ट पथ जानकारी के बिना मानक लिनक्स / यूनिक्स तिथि प्रदर्शन / सेट कमांड पर ले जाती है (अर्थात, आपका पर्यावरण पथ चर सही रूप से कॉन्फ़िगर किया गया है)।


OS XI पर डेट कमांड से पहले स्पेस की जरूरत थी। अफसोस की बात है कि यह प्रत्येक पंक्ति के लिए कमांड का पुनर्मूल्यांकन करने के लिए प्रतीत नहीं होता है। जैसे दूसरों ने सुझाव दिया है, मैं टाइमस्टैम्प को टेल-एफ में जोड़ने की कोशिश कर रहा हूं।
मार्क बेनेट

2

ऊपर natevw और फ्रैंक Ch से कुछ जवाब मिलाते हुए । Eigler।

इसमें मिलीसेकंड होता है, dateहर बार बाहरी कमांड को कॉल करने से बेहतर प्रदर्शन करता है और अधिकांश सर्वरों में पर्ल पाया जा सकता है।

tail -f log | perl -pne '
  use Time::HiRes (gettimeofday);
  use POSIX qw(strftime);
  ($s,$ms) = gettimeofday();
  print strftime "%Y-%m-%dT%H:%M:%S+$ms ", gmtime($s);
  '

फ्लश के साथ वैकल्पिक संस्करण और एक लूप में पढ़ें:

tail -f log | perl -pne '
  use Time::HiRes (gettimeofday); use POSIX qw(strftime);
  $|=1;
  while(<>) {
    ($s,$ms) = gettimeofday();
    print strftime "%Y-%m-%dT%H:%M:%S+$ms $_", gmtime($s);
  }'

1
उपरोक्त दो खामियां: 1. $ ms संरेखित नहीं है और शून्य-गद्देदार है। 2. लॉग में कोई भी% कोड मंगवाए जाएंगे। इस प्रकार प्रिंट लाइन के बजाय, मैंने उपयोग किया: printf "%s+%06d %s", (strftime "%Y-%m-%dT%H:%M:%S", gmtime($s)), $ms, $_;
सिमोन पिकअप

2
$ cat somefile.txt | sed "s/^/`date`/"

आप ऐसा कर सकते हैं ( ग्नू / सेड के साथ ):

$ some-command | sed "x;s/.*/date +%T/e;G;s/\n/ /g"

उदाहरण:

$ { echo 'line1'; sleep 2; echo 'line2'; } | sed "x;s/.*/date +%T/e;G;s/\n/ /g"
20:24:22 line1
20:24:24 line2

बेशक, आप कार्यक्रम की तारीख के अन्य विकल्पों का उपयोग कर सकते हैं । बस date +%Tआपको जो चाहिए उसकी जगह लें ।


1

caerwyn का जवाब सबरूटीन के रूप में चलाया जा सकता है, जो प्रति पंक्ति नई प्रक्रियाओं को रोक देगा:

timestamp(){
   while read line
      do
         echo `date` $line
      done
}

echo testing 123 |timestamp

3
यह कैसे dateहर पंक्ति में पैदा होने से रोकता है?
गयूम

@ गयूम यह तारीख को हर पंक्ति में नहीं रोका जा सकता है। यह हर पंक्ति को खोल देने से रोकता है । मुझे लगता है कि आप को हरा timestamp() { while read line; do echo "$(date) $line"; done; }; export -f timestampमें जोड़े कुछ इस तरह होगा: एक स्क्रिप्ट है कि आप स्रोत में।
चिकना करें

दिनांक को उपप्रकार के रूप में कॉल करने का अर्थ है कि इसे प्रत्येक पंक्ति के लिए स्पॉन करना, हालांकि आप स्क्रिप्ट को पहले स्थान पर लॉन्च करते हैं।
पीटर हैनसेन

3
dateहर पंक्ति के लिए स्पॉनिंग कमांड को रोकने के लिए, % (डेट्सपेक) टी प्रारूप के printfसाथ बैश बिलिन का उपयोग करने का प्रयास करें । तो ऐसा लग सकता है । शेल बिल्‍डिंग नहीं होगी। Datespec प्रारूप की तरह है यानी प्रारूपों। इसके लिए बैश की आवश्यकता होती है, यह सुनिश्चित नहीं होता है कि यह किस संस्करण का समर्थन करता है । timestamp() { while IFS= read -r line; do printf "%(%F %T)T %s\n" -1 "$line"; done; }strftime(3)dateprintf
मिन्दुगास कुबीलियस

1

अस्वीकरण : मैं जो प्रस्ताव पेश कर रहा हूं, वह यूनिक्स निर्मित उपयोगिता नहीं है।

मैंने कुछ दिन पहले इसी तरह की समस्या का सामना किया था। मुझे ऊपर दिए गए समाधानों की वाक्य रचना और सीमाएं पसंद नहीं थीं, इसलिए मैंने जल्दी से मेरे लिए काम करने के लिए गो में एक कार्यक्रम रखा।

आप यहां टूल की जांच कर सकते हैं: प्रीफाइम

GitHub प्रोजेक्ट के Releases अनुभाग में Linux, MacOS और Windows के लिए प्रीबिल्ट निष्पादन योग्य हैं ।

उपकरण अधूरा आउटपुट लाइनों को संभालता है और (मेरे दृष्टिकोण से) एक अधिक कॉम्पैक्ट सिंटैक्स है।

<command> | preftime

यह आदर्श नहीं है, लेकिन अगर मैं किसी की मदद करता हूं तो मैं इसे साझा करूंगा।


0

साथ यह कर dateऔर trऔर xargsOSX पर:

alias predate="xargs -I{} sh -c 'date +\"%Y-%m-%d %H:%M:%S\" | tr \"\n\" \" \"; echo \"{}\"'"
<command> | predate

यदि आप मिलीसेकंड चाहते हैं:

alias predate="xargs -I{} sh -c 'date +\"%Y-%m-%d %H:%M:%S.%3N\" | tr \"\n\" \" \"; echo \"{}\"'"

लेकिन ध्यान दें कि OSX पर, दिनांक आपको% N विकल्प नहीं देता है, इसलिए आपको gdate ( brew install coreutils) को स्थापित करने की आवश्यकता होगी और अंत में इस पर:

alias predate="xargs -I{} sh -c 'gdate +\"%Y-%m-%d %H:%M:%S.%3N\" | tr \"\n\" \" \"; echo \"{}\"'"

-1

यदि आप जो मूल्य प्रीपेड कर रहे हैं, वह हर लाइन पर समान है, तो फ़ाइल के साथ एमएसीएस को फायर करें, फिर:

Ctrl + <space>

फ़ाइल की शुरुआत में (उस स्थान को चिह्नित करने के लिए), फिर अंतिम पंक्ति की शुरुआत तक स्क्रॉल करें (Alt +> फ़ाइल के अंत में जाएगा ... जिसमें संभवतः Shift कुंजी भी शामिल होगी, फिर Ctrl + (उस लाइन की शुरुआत में जाने के लिए) और:

Ctrl + x r t

आपके द्वारा निर्दिष्ट आयत में सम्मिलित करने के लिए कौन सी कमांड है (0 चौड़ाई का एक आयत)।

2008-8-21 6:45 अपराह्न <दर्ज करें>

या जो भी आप प्रीपेंड करना चाहते हैं ... तो आप देखेंगे कि 0 चौड़ाई आयत के भीतर हर पंक्ति के लिए प्रचलित पाठ है।

अद्यतन करें: मुझे लगा कि आप एक ही तारीख नहीं चाहते हैं, इसलिए यह काम नहीं करेगा ... हालाँकि आप इसे कुछ अधिक जटिल कस्टम मैक्रो के साथ emacs में कर सकते हैं, लेकिन फिर भी, इस तरह का आयत संपादन है जानकर बहुत अच्छा लगा ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.