স্টিডিনে টাইমস্ট্যাম্পগুলি পুনরায় চাপানোর জন্য কি কোনও ইউনিক্স ইউটিলিটি রয়েছে?


168

পাইথনে আমি এটির জন্য একটি দ্রুত ছোট স্ক্রিপ্ট লিখে শেষ করেছি, তবে আমি ভাবছিলাম যে এমন কোনও ইউটিলিটি রয়েছে যা আপনি পাঠ্যকে খাওয়াতে পারবেন যেখানে প্রতিটি লাইনকে কিছু পাঠ্য সহ প্রিপেন্ড করবে - আমার নির্দিষ্ট ক্ষেত্রে, একটি টাইমস্ট্যাম্প। আদর্শভাবে, ব্যবহারটি এমন কিছু হবে:

cat somefile.txt | prepend-timestamp

(আপনি খারাপ উত্তর দেওয়ার আগে, আমি এটি চেষ্টা করেছি:

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

তবে এটি কেবলমাত্র ডায়াল কমান্ডকে একবার মূল্যায়ন করে যখন সেড কার্যকর করা হয়, সুতরাং একই টাইমস্ট্যাম্পটি প্রতিটি লাইনে ভুলভাবে সংশোধন করা হয়))


কি cat somefile.txtএকটু "বিভ্রান্তিকর"? আমি আশা করি এটি "একবারে" ঘটবে এবং একটি একক টাইমস্ট্যাম্প লাগবে। এই একটি ভাল পরীক্ষা প্রোগ্রাম হবে না: (echo a; sleep 1; echo b; sleep 3; echo c; sleep 2)?
সিরো সান্তিলি 郝海东 冠状 病 六四 事件

উত্তর:


185

ব্যবহার করার চেষ্টা করতে পারে awk:

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

আপনি <command>লাইন বাফার আউটপুট উত্পাদন করে তা নিশ্চিত করার প্রয়োজন হতে পারে , অর্থাৎ এটি প্রতিটি লাইনের পরে তার আউটপুট প্রবাহকে ফ্লাশ করে; টাইমস্ট্যাম্প awkযোগ করার সময় লাইনের শেষটি এর ইনপুট পাইপে প্রদর্শিত হবে।

যদি খোলার ত্রুটিগুলি দেখায় তবে gawkতার পরিবর্তে চেষ্টা করুন।


31
আমার সিস্টেমে 'অ্যাডক' নিজেই বাফার করছিল। (এটি লগ ফাইলগুলির জন্য সমস্যাযুক্ত হতে পারে)। আমি এটি ব্যবহার করে স্থির করেছি: awk '{প্রিন্ট স্ট্রফটাইম ("% Y-% m-% dT% এইচ:% এম:% এস"), $ 0; fflush (); :28 '
ব্যবহারকারী 47741

19
স্ট্রাইফটাইম () হ'ল একটি জিএনইউ অ্যাজক এক্সটেনশান হিসাবে উপস্থিত হয়, সুতরাং আপনি যদি ম্যাক ওএসে থাকেন তবে উদাহরণস্বরূপ, জাজের পরিবর্তে গাওক ব্যবহার করুন।
জো শ

বাশ কতটা শক্তিশালী তা আমাকে অবাক করে দিয়ে থামেনি। আমি ভাবিনি যে এই জটিল কাজের জন্য এত সহজ সমাধান হবে।

2
OS X এর ব্যবহারকারীদের জন্য, আপনি ইনস্টল করতে হবে gawkএবং ব্যবহার পরিবর্তে যে awk। আপনার যদি ম্যাকপোর্টস থাকে: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মুরতুলগুলি থেকে আপনি যে ইনপুট দেন তা প্রতিটি লাইনে একটি টাইমস্ট্যাম্প তৈরি করে। আপনি স্ট্রফটাইম ব্যবহার করে এটি ফর্ম্যাট করতে পারেন।

$ 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 | tsJan 29 19:58:31 -bash: bad: command not found
স্ট্যাডারকে

আমি সময়ের ফর্ম্যাটটি ব্যবহার করতে চাই 2014 Mar 21 18:07:28। আমি কীভাবে এটি পেতে পারি?
বেকো

@ বেকো - ম্যানুয়াল পৃষ্ঠা অনুসারে , strftimeআর্গুমেন্ট হিসাবে একটি ফর্ম্যাট স্ট্রিং দিন: [.. command ..] | ts '%Y %b %d %T'উদাহরণস্বরূপ।
টবি স্পাইট

2
ওএস এক্স এর জন্য brew install moreutils,। ইউটিসি আউটপুট দিতে, আপনি স্থানীয়ভাবে টিজেড সেট করতে পারেন, যেমনls -l |TZ=UTC ts '%Y-%m-%dT%H:%M:%SZ'
কর্মকাজে

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
এটি দুর্দান্ত সমাধান, তবে পাইপ আউটপুট বা সাবহেলড আউটপুট নিয়ে কাজ করবে না। এটি কেবলমাত্র কোনও প্রোগ্রাম বা স্ক্রিপ্টের আউটপুট পুনরায় ফর্ম্যাট করবে যা আপনি এটি একটি আর্গুমেন্ট হিসাবে দেন।
slm

1
টিকা-আউটপুট সুন্দরভাবে কাজ করে এবং ব্যবহার করা সহজ, তবে এটি খুব ধীর।
পল ব্রান্নান

31

সম্ভাব্যতম সহজতমটির জন্য দেওয়া উত্তরগুলি বিতরণ করা:

unbuffer $COMMAND | ts

উবুন্টুতে, তারা প্রত্যাশা-দেব এবং মুরতাদির প্যাকেজগুলি থেকে আসে।

sudo apt-get install expect-dev moreutils

1
এটি expect, না expect-dev, তবে পূর্ববর্তীটি পূর্বের দিকে টানে তাই এটি কাজ করে। (উবুন্টু 14.10, আমি অবাক হই যে বাইনারিটি কোনও সময়ে অন্য কোনও প্যাকেজে সরানো হয়েছিল
if

উবুন্টু 14.04 এলটিএসের জন্য, এটি এখনও রয়েছেexpect-dev
উইলিম

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
এই পার্ল উদাহরণটি আমার জন্য বিশেষভাবে কার্যকর ছিল কারণ আমি উবুন্টু স্থাপনার একজন ব্যবহারকারী হিসাবে কাজ করছিলাম, যা স্পষ্টতই 'গাওক' এর পরিবর্তে 'মওক' ব্যবহার করে - এবং এতে স্ট্রফটাইম ফাংশন নেই। ধন্যবাদ!
অপেলো

4
ডিফল্ট উবুন্টু ইনস্টলটিতে এটি কার্যকর হবে + আমি tail -f /path/to/log | perl -pne 'use POSIX qw(strftime); print strftime "%Y-%m-%dT%H:%M:%SZ ", gmtime();'সহজ সংস্করণ ফলনের পরিবর্তে ওয়্যাকোর পরিবর্তে একটি আইএসও ৮60০১ / আরএফসি 3339 শৈলীর তারিখ পেয়েছি।
natevw

1
আপনি যদি টাইমস্ট্যাম্পড লগ আউটপুটটি আসার সাথে সাথে দেখতে সক্ষম হতে চান তবে BEGIN { $|++; }পার্লকে প্রতিটি লাইন দিয়ে আউটপুট ফ্লাশ করার জন্য মুদ্রণ বিবরণীর আগে যুক্ত করা সহায়ক হতে পারে ।

2
আপনি পার্ল স্ক্রিপ্টটি আরও ছোট করতে পারেন ls | perl -pne 'print localtime." "'। স্ট্যালার কনটেক্সটেশনের কারণে স্কেলারের রূপান্তর ঘটে।
রাহুল

আপনি উভয় -pএবং -nবিকল্প ব্যবহার করবেন না কেন ? এটি দেখে মনে হচ্ছে -nঅপ্রয়োজনীয় হলে আপনি নির্দিষ্ট করেছেন -p
কিউবারিক

19

কেবল এটি এখানে ফেলে দেওয়া হবে: ডেমোনটোলে একজোড়া ইউটিলিটি রয়েছে যাকে বলা হয় তাইউইএনএন এবং তাইউইনলোকাল বার্তা লগ ইন করার টাইমস্ট্যাম্প prepending জন্য তৈরি করা হয়।

উদাহরণ:

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

এখানে আমার অজানা সমাধান (সি: \ বিন ডিরেক্টরিতে ইনস্টল করা এমকেএস সরঞ্জাম সহ একটি উইন্ডোজ / এক্সপি সিস্টেম থেকে)। এটি মিমি / ডিডি এইচ: মিমি আকারে বর্তমান তারিখ এবং সময় যুক্ত করার জন্য ডিজাইন করা হয়েছে প্রতিটি লাইনটি পড়ার সাথে সাথে সিস্টেম থেকে সেই টাইমস্ট্যাম্প এনেছে প্রতিটি লাইনের শুরুতে। আপনি অবশ্যই টাইমস্ট্যাম্পটি একবারে আনতে এবং প্রতিটি রেকর্ডে (সমস্ত একই) টাইমস্ট্যাম্প যুক্ত করতে বিগিন প্যাটার্নটি ব্যবহার করতে পারেন। আমি লগ বার্তা তৈরি হওয়ার সময় টাইমস্ট্যাম্পের সাহায্যে স্টডআউটে উত্পন্ন হওয়া লগ ফাইলটি ট্যাগ করার জন্য এটি করেছি did

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

যেখানে "প্যাটার্ন" হ'ল একটি স্ট্রিং বা রেজেক্স (উদ্ধৃতি ব্যতীত) ইনপুট লাইনে মিলবে এবং আপনি সমস্ত ইনপুট লাইনের সাথে মিল রাখতে চাইলে optionচ্ছিক।

এটি লিনাক্স / ইউনিক্স সিস্টেমগুলিতেও কাজ করা উচিত, কেবল লাইনটি ছেড়ে সি \\: \\ বিন \\ থেকে মুক্তি পান

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

এটি অবশ্যই অনুমান করে যে "তারিখ" কমান্ডটি আপনাকে নির্দিষ্ট পাথ তথ্য ছাড়াই স্ট্যান্ডার্ড লিনাক্স / ইউনিক্স তারিখ প্রদর্শন / সেট কমান্ডে নিয়ে আসে (এটি হল আপনার পরিবেশের PATH ভেরিয়েবলটি সঠিকভাবে কনফিগার করা হয়েছে)।


ওএস ইলেভেনে ডেট কমান্ডের আগে একটি স্পেস প্রয়োজন। দুঃখজনকভাবে প্রতিটি লাইনের জন্য কমান্ডটি পুনরায় মূল্যায়ন করার মতো মনে হচ্ছে না। অন্যরা যেমন পরামর্শ দিয়েছে, তেমন আমি টাইমস্ট্যাম্পগুলি টেল-ফেমে যুক্ত করার চেষ্টা করছি।
মার্ক বনেট

2

নেটভডব্লু থেকে উপরের কয়েকটি উত্তর মিশ্রণ এবং ফ্রাঙ্ক সিএইচ । 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
উপরোক্ত দুটি ত্রুটি: ১.১ এমএস প্রান্তিক এবং শূন্য প্যাডযুক্ত নয়। ২. লগের যে কোনও% কোড ম্যাঙ্গেল করা হবে। সুতরাং প্রিন্ট লাইনের পরিবর্তে, আমি ব্যবহার করেছি: printf "%s+%06d %s", (strftime "%Y-%m-%dT%H:%M:%S", gmtime($s)), $ms, $_;
সাইমন পিকআপ

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

আপনি এটি করতে পারেন ( gnu / সেড সহ ):

$ 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 উত্তর একটি subroutine হিসাবে চালানো যেতে পারে, যা প্রতি লাইনে নতুন প্রক্রিয়া প্রতিরোধ করবে:

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

echo testing 123 |timestamp

3
কীভাবে dateপ্রতি লাইনে স্প্যানিং হওয়া থেকে রোধ করা যায়?
Gyom

@ জ্যোম এটি প্রতিটি লাইনে তারিখ তৈরি করতে বাধা দেয় না। এটি শেলকে প্রতিটি লাইনের স্প্যানিং থেকে বাধা দেয় । আমি এটিকে যুক্ত করব যাতে আপনি বাশতে কিছু করতে পারেন: timestamp() { while read line; do echo "$(date) $line"; done; }; export -f timestampআপনার উত্স অনুসারে কোনও স্ক্রিপ্টে।
smbear

সাব-প্রসেস হিসাবে ডেট ডাকা মানে এখনও প্রতিটি লাইনের জন্য এটি তৈরি করা হয়, তবে আপনি স্ক্রিপ্টটি প্রথম স্থানে চালু করেন।
পিটার হানসেন

3
dateপ্রতিটি লাইনের স্প্যানিং কমান্ড প্রতিরোধ করতে , % (ডেটস্পেক) টি ফর্ম্যাট printfসহ ব্যাশ বিল্টিন ব্যবহার করার চেষ্টা করুন । সুতরাং এটি দেখতে মত হতে পারে timestamp() { while IFS= read -r line; do printf "%(%F %T)T %s\n" -1 "$line"; done; }। শেল বিল্টিনগুলি ফুটে উঠবে না। Datespec বিন্যাস মত হল strftime(3)অর্থাত dateফরম্যাটের। এর জন্য বাশ দরকার, কোন সংস্করণটি সেই printfস্পেসিফারটিকে সমর্থন করে তা নিশ্চিত নয় ।
মিনডোগাস কুবিলিয়াস

1

দাবি পরিত্যাগী : আমি যে সমাধানটির প্রস্তাব দিচ্ছি সেটি কোনও ইউনিক্স অন্তর্নির্মিত ইউটিলিটি নয়।

কিছুদিন আগেও আমি একই ধরণের সমস্যার মুখোমুখি হয়েছি। উপরের সমাধানগুলির বাক্য গঠন এবং সীমাবদ্ধতাগুলি আমি পছন্দ করি না, তাই আমি আমার কাজটি করার জন্য গো তে একটি প্রোগ্রাম খুব দ্রুত এক সাথে রাখলাম।

আপনি এখানে সরঞ্জামটি চেক করতে পারেন: প্রিফটাইম

গিটহাব প্রকল্পের রিলিজ বিভাগে লিনাক্স, ম্যাকোস এবং উইন্ডোজের প্রাক-বিল্ট এক্সিকিউটেবল রয়েছে ।

সরঞ্জামটি অসম্পূর্ণ আউটপুট লাইনগুলি পরিচালনা করে এবং (আমার দৃষ্টিকোণ থেকে) আরও কমপ্যাক্ট সিনট্যাক্স রয়েছে।

<command> | preftime

এটি আদর্শ নয়, তবে যদিও এটি কাউকে সহায়তা করে তবে আমি এটি ভাগ করে নিই।


0

সঙ্গে এরকম dateএবং trএবং xargsওএসএক্স করুন:

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 \"{}\"'"

তবে মনে রাখবেন যে ওএসএক্স-এ তারিখ আপনাকে% 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 +> ফাইলের শেষে যাবে ... যা সম্ভবত শিফট কীটিও জড়িত থাকবে, তারপরে Ctrl + এ লাইনের শুরুতে যেতে) এবং:

Ctrl + + x r t

আপনার সুনির্দিষ্ট আয়তক্ষেত্রটি সন্নিবেশ করানোর জন্য কোন আদেশ (0 প্রস্থের একটি আয়তক্ষেত্র)।

2008-8-21 6:45 pm <enter>>

বা আপনি যেহেতু প্রিপেন্ড করতে চান ... ... তবে আপনি সেই পাঠ্যটি 0 প্রস্থের আয়তক্ষেত্রের মধ্যে প্রতিটি লাইনে প্রপেন্ডড দেখতে পাবেন।

আপডেট: আমি ঠিক বুঝতে পেরেছি যে আপনি একই তারিখটি চান না, সুতরাং এটি কাজ করবে না ... যদিও আপনি কিছুটা জটিল জটিল কাস্টম ম্যাক্রো দিয়ে ইম্যাক্সে এটি করতে সক্ষম হতে পারেন তবে তবুও, এই জাতীয় আয়তক্ষেত্র সম্পাদনাটি সম্পর্কে জেনে খুব সুন্দর ...

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.