විධානයකින් එක් එක් නිමැවුම් පේළියට කාලරාමුව සකස් කිරීම


211

විධානයකින් එක් එක් නිමැවුම් පේළියට කාලරාමුව සකස් කිරීමට මම කැමැත්තෙමි. උදාහරණයක් වශයෙන්:

foo
bar
baz

බවට පත්වේ

[2011-12-13 12:20:38] foo
[2011-12-13 12:21:32] bar
[2011-12-13 12:22:20] baz

... පෙර සැකසූ වේලාව වන්නේ රේඛාව මුද්‍රණය කළ වේලාවයි. මට මෙය සාක්ෂාත් කරගත හැක්කේ කෙසේද?


Answers:


318

moreutils වලට tsමෙය මනාව කරන දේ ඇතුළත් වේ :

command | ts '[%Y-%m-%d %H:%M:%S]'

එමඟින් ලූපයක අවශ්‍යතාවයද ඉවත් කරයි, සෑම නිමැවුම් පේළියකටම කාලරාමුවක් තබා ඇත.

$ echo -e "foo\nbar\nbaz" | ts '[%Y-%m-%d %H:%M:%S]'
[2011-12-13 22:07:03] foo
[2011-12-13 22:07:03] bar
[2011-12-13 22:07:03] baz

එම සේවාදායකය නැවත පැමිණි විට ඔබ නැවත ආරම්භ කළ බව දැන ගැනීමට ඔබට අවශ්‍යද? ධාවනය කරන්න ping | ts, ගැටළුව විසඳා ඇත: ඩී.


9
මම මේ ගැන නොදැන සිටියේ කෙසේද?!?!?! මෙය පුදුම සහගත ලෙස වලිගය සම්පූර්ණ කරයි! tail -f /tmp/script.results.txt | ts
බ un නෝ බ්‍රොනොස්කි

4
මට ts විධානයක් නොමැති නම්, මා භාවිතා කළ යුත්තේ කුමක්ද?
ekassis

3
එය ක්‍රියා නොකරන්නේ නම්, ssh -v 127.0.0.1 2>&1 | ts
stderr stdout

1
sudo apt install moreutilsඩේබියන් සහ yum install moreutilsෆෙඩෝරා මත කිරීමෙන් ස්ථාපනය කරන්න .
Stiffy2000

5
පරාමිතිය පෙන්වා -sදීම ප්‍රයෝජනවත් යැයි මම සිතමි . එය විධානයෙහි ධාවන කාලය පෙන්වයි. මම පෞද්ගලිකව දෙකම භාවිතා වැනි tsසහ ts -sඑම අවස්ථාවේ දී. මේ වගේ දෙයක් පෙනේ : command | ts -s '(%H:%M:%.S)]' | ts '[%Y-%m-%d %H:%M:%S'. මෙය මෙවැනි ලොග් රේඛා සකස් කරයි:[2018-12-04 08:31:00 (00:26:28.267126)] Hai <3
BrainStone

113

පළමුවෙන්ම, මෙම කාලරාමු ඇත්ත වශයෙන්ම සිදුවීමක් නියෝජනය කරනු ඇතැයි ඔබ අපේක්ෂා කරන්නේ නම්, බොහෝ වැඩසටහන් රේඛීය බෆරින් (අනෙක් ඒවාට වඩා ආක්‍රමණශීලී ලෙස) සිදු කරන බැවින්, මෙය මුල් රේඛාවට ඇති කාලයට ආසන්න යැයි සිතීම වැදගත් බව මතක තබා ගන්න. සිදුවෙමින් පවතින ක්‍රියාවක කාලරාමුවකට වඩා මුද්‍රණය කර ඇත.

මෙය සිදු කිරීම සඳහා ඔබේ විධානයට දැනටමත් ආවේණික අංගයක් නොමැතිදැයි පරීක්ෂා කිරීමට ඔබට අවශ්‍ය විය හැකිය. උදාහරණයක් ලෙස, ping -Dසමහර pingඅනුවාදවල පවතින අතර , එක් එක් පේළියට පෙර යුනික්ස් යුගයේ සිට කාලය මුද්‍රණය කරයි. ඔබේ විධානයට තමන්ගේම ක්‍රමවේදයක් නොමැති නම්, කෙසේ වෙතත්, භාවිතා කළ හැකි ක්‍රම සහ මෙවලම් කිහිපයක් තිබේ, අනෙක් ඒවා අතර:

පොසික්ස් කවචය

මතක තබා ගන්න, බොහෝ ෂෙල් වෙඩි ඔවුන්ගේ නූල් අභ්‍යන්තරව cstrings ලෙස ගබඩා කර ඇති බැවින්, ආදානයේ ශුන්‍ය අක්‍ෂරය ( \0) අඩංගු නම් , එය රේඛාව අකාලයේ අවසන් වීමට හේතු විය හැක.

command | while IFS= read -r line; do printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$line"; done

GNU awk

command | gawk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0 }'

පර්ල්

command | perl -pe 'use POSIX strftime; print strftime "[%Y-%m-%d %H:%M:%S] ", localtime'

පයිතන්

command | python -c 'import sys,time;sys.stdout.write("".join(( " ".join((time.strftime("[%Y-%m-%d %H:%M:%S]", time.localtime()), line)) for line in sys.stdin )))'

රූබි

command | ruby -pe 'print Time.now.strftime("[%Y-%m-%d %H:%M:%S] ")'

4
මෙහි ඇති එක් ගැටළුවක් නම්, බොහෝ වැඩසටහන් ටර්මිනලය වෙනුවට පයිප්පයක් වන විට ඊටත් වඩා ප්‍රතිදාන බෆරින් සක්‍රීය කිරීමයි.
cjm

4
jcjm - ඇත්ත. සමහර නිමැවුම් බෆරින් භාවිතා කිරීමෙන් සමනය කළ හැකිය stdbuf -o 0, නමුත් වැඩසටහන එහි ප්‍රතිදාන බෆරින් අතින් හසුරුවන්නේ නම්, එය උදව් නොකරනු ඇත (ප්‍රතිදාන බෆරයේ ප්‍රමාණය අක්‍රීය කිරීමට / අඩු කිරීමට විකල්පයක් නොමැති නම්).
ක්‍රිස් ඩවුන්

3
පයිතන් සඳහා, ඔබට රේඛීය python -u
බෆරින්

WBwmat No. ... for x in sys.stdinරේඛා හරහා ඒවා සියල්ලම මතකයේ රඳවා නොගෙන නැවත ගමන් කරයි.
ක්‍රිස් ඩවුන්

මෙය කරන්න, ඔබට බෆරයක් ලැබේ ... 1 1 1 1 1 සඳහා; නිදාගන්න 1; echo; අවසන් | python -c 'import sys, time; sys.stdout.write ("". join (("" .ජොයින් ((time.strftime ("[% Y-% m-% d% H:% M:% S] ", time.gmtime ()), line)) sys.stdin හි පේළිය සඳහා))) '
ChuckCottrill

47

රේඛීයව ඩෙල්ටා මැනීම සඳහා, gnomon උත්සාහ කරන්න .

වෙනත් විධානයක සම්මත නිමැවුමට කාලරාමු තොරතුරු සකස් කිරීම විධාන රේඛා උපයෝගීතාවයකි. මෙතරම් කාලයක් ගතවන දේ පිළිබඳ record තිහාසික වාර්තාවක් ඔබ කැමති දිගුකාලීන ක්‍රියාවලීන් සඳහා ප්‍රයෝජනවත් වේ.

Gnomon වෙත ඕනෑම දෙයක් පයිප්ප කිරීම මඟින් එක් එක් පේළියට කාලරාමුව සකස් කරනු ඇත, එමඟින් එම රේඛාව බෆරයේ අවසාන පේළිය කොපමණ වේලාවක්ද යන්න පෙන්නුම් කරයි - එනම් ඊළඟ පේළිය දර්ශණය වීමට කොපමණ කාලයක් ගතවේද යන්න. පෙරනිමියෙන්, එක් එක් පේළිය අතර ගත වූ තත්පර ගණන gnomon මඟින් පෙන්වනු ඇත, නමුත් එය වින්‍යාසගත කළ හැකිය.

gnomon demo


2
tsසජීවී ක්‍රියාවලි භාවිතා කිරීමේදී හොඳ විකල්පයක් ලෙස පෙනේ . අතර tsවඩා හොඳ ඒකාකාරී ක්රියාවලීන් සඳහා සුදුසු වේ.
BrainStone

7

මම ඉහත අදහස් දැක්වීමට කැමැත්තක් දැක්වුවද මට කීර්තිමත් ලෙස එය කළ නොහැකිය. කෙසේ වෙතත්, ඉහත පර්ල් නියැදිය පහත පරිදි නිරවුල් කළ හැකිය:

command | perl -pe 'use POSIX strftime; 
                    $|=1; 
                    select((select(STDERR), $| = 1)[0]);
                    print strftime "[%Y-%m-%d %H:%M:%S] ", localtime'

පළමු '$ |' STDOUT ඉවත් කරන්න. දෙවැන්න වත්මන් පෙරනිමි ප්‍රතිදාන නාලිකාව ලෙස stderr සකසා එය ඉවත් කරයි. තේරීම select | හි මුල් සැකසුම ලබා දෙන බැවින්, තේරීමක් ඇතුළත තේරීමෙන් ඔතා, අපි reset | එහි පෙරනිමිය වන STDOUT.

ඔව්, ඔබට පේස්ට් කපන්න පුළුවන්. මම එය නිරවද්‍යතාව සඳහා බහු-රේඛා කර ඇත.

ඔබට නිශ්චිතවම ලබා ගැනීමට අවශ්‍ය නම් (ඔබට වේලාව :: කුලී ස්ථාපනය කර ඇත):

command | perl -pe 'use POSIX strftime; use Time::HiRes gettimeofday;
                    $|=1; 
                    select((select(STDERR), $| = 1)[0]);
                    ($s,$ms)=gettimeofday();
                    $ms=substr(q(000000) . $ms,-6);
                    print strftime "[%Y-%m-%d %H:%M:%S.$ms]", localtime($s)'

1
සම්මත නොවන පැකේජ ස්ථාපනය නොකර, චාම් එකක් මෙන් ක්‍රියා කරයි.
ජේ ටේලර්

7

රයන් ගේ පෝස්ට් සිත්ගන්නාසුලු අදහසක් සපයයි, කෙසේ වෙතත් එය කරුණු කිහිපයකින් අසමත් වේ. අත්හදා බැලීමේදී tail -f /var/log/syslog | xargs -L 1 echo $(date +'[%Y-%m-%d %H:%M:%S]') $1 , stdoutතත්පර ගණනක වෙනසක් සමඟ පසුව පැමිණියද කාලරාමුව එලෙසම පවතින බව මම දුටුවෙමි . මෙම ප්‍රතිදානය සලකා බලන්න:

[2016-07-14 01:44:25] Jul 14 01:44:32 eagle dhclient[16091]: DHCPREQUEST of 192.168.0.78 on wlan7 to 255.255.255.255 port 67 (xid=0x411b8c21)
[2016-07-14 01:44:25] Jul 14 01:44:34 eagle avahi-daemon[740]: Joining mDNS multicast group on interface wlan7.IPv6 with address fe80::d253:49ff:fe3d:53fd.
[2016-07-14 01:44:25] Jul 14 01:44:34 eagle avahi-daemon[740]: New relevant interface wlan7.IPv6 for mDNS.

මගේ විසඳුමක් යෝජනා සමාන වේ, කෙසේ වෙතත් නිසි කාලය තැබීෙම් හා භාවිතයන් ඊට වඩා තරමක් එහා මෙහා ගෙන යා හැකි සපයයි printfවඩාecho

| xargs -L 1 bash  -c 'printf "[%s] %s\n" "$(date +%Y-%m-%d\ %H:%M:%S )" "$*" ' bash

ඇයි bash -c '...' bash? -cවිකල්පය නිසා , පළමු තර්කය පවරා $0ඇති අතර ප්‍රතිදානයේ නොපෙන්වයි. පිළිබඳ නිසි විස්තරයක් සඳහා ඔබේ කවචයේ අත්පොත බලන්න-c

tail -f /var/log/syslogමගේ වයිෆයි සමඟ විසන්ධි කිරීම සහ නැවත සම්බන්ධ කිරීම සමඟ (ඔබට අනුමාන කළ හැකි පරිදි) මෙම විසඳුම පරීක්ෂා කිරීමෙන්, දෙකම dateසහ syslogපණිවිඩ මගින් සපයනු ලබන නිසි කාල මුද්දරය පෙන්වා ඇත.

බෑෂ් ඕනෑම බෝර්න් වැනි කවචයකින් ප්‍රතිස්ථාපනය කළ හැකිය, kshඑසේත් නැතිනම් dashඅවම වශයෙන් -cවිකල්පයක් ඇති ඒවා සමඟ කළ හැකිය.

විභව ගැටළු:

විසඳුමට තිබීම අවශ්‍ය xargsවන අතර එය POSIX අනුකූල පද්ධතිවල ඇත, එබැවින් බොහෝ යුනික්ස් වැනි පද්ධති ආවරණය කළ යුතුය. ඔබේ පද්ධතිය POSIX නොවන හෝ නොමැති නම් නිසැකවම ක්‍රියා නොකරනු ඇතGNU findutils


5

බොහෝ පිළිතුරු භාවිතා කිරීමට යෝජනා dateකළත් එය මන්දගාමී ය. ඔබේ බෑෂ් අනුවාදය 4.2.0 ට වඩා වැඩි නම් printfඒ වෙනුවට භාවිතා කිරීම වඩා හොඳය , එය බාෂ් බිල්ඩින් ය. ඔබට පැරණි බැෂ් අනුවාදයන්ට සහය දැක්වීමට අවශ්‍ය නම් ඔබට logශ්‍රිතය නිර්මාණය කළ හැක්කේ බැෂ් අනුවාදය මත ය:

TIMESTAMP_FORMAT='%Y-%m-%dT%H:%M:%S'
# Bash version in numbers like 4003046, where 4 is major version, 003 is minor, 046 is subminor.
printf -v BV '%d%03d%03d' ${BASH_VERSINFO[0]} ${BASH_VERSINFO[1]} ${BASH_VERSINFO[2]}
if ((BV > 4002000)); then
log() {
    ## Fast (builtin) but sec is min sample for most implementations
    printf "%(${TIMESTAMP_FORMAT})T %5d %s\n" '-1' $$ "$*"  # %b convert escapes, %s print as is
}
else
log() {
    ## Slow (subshell, date) but support nanoseconds and legacy bash versions
    echo "$(date +"${TIMESTAMP_FORMAT}") $$ $*"
}
fi

වේග වෙනස්කම් බලන්න:

user@host:~$time for i in {1..10000}; do printf "%(${TIMESTAMP_FORMAT})T %s\n" '-1' "Some text" >/dev/null; done

real    0m0.410s
user    0m0.272s
sys     0m0.096s
user@host:~$time for i in {1..10000}; do echo "$(date +"${TIMESTAMP_FORMAT}") Some text" >/dev/null; done

real    0m27.377s
user    0m1.404s
sys     0m5.432s

UPD: ඒ වෙනුවට භාවිතා කිරීම $(date +"${TIMESTAMP_FORMAT}")වඩා හොඳ $(exec date +"${TIMESTAMP_FORMAT}")හෝ $(exec -c date +"${TIMESTAMP_FORMAT}")වේගවත් ක්‍රියාත්මක කිරීම වෙනුවට.


1

ඔබට මෙය කළ හැක්කේ dateසහ xargs:

... | xargs -L 1 echo `date +'[%Y-%m-%d %H:%M:%S]'` $1

පැහැදිලි කිරීම:

xargs -L 1සෑම ආදාන පේළියක් සඳහාම ඉදිරියට යන විධානය ක්‍රියාත්මක කිරීමට xargs ට පවසන අතර, එය එසේ වන විට එය පළමු පේළියේම ගමන් කරයි. echo `date +'[%Y-%m-%d %H:%M:%S]'` $1මූලික වශයෙන් දිනය අවසානයේ ආදාන තර්කය සමඟ ප්‍රතිරාවය කරයි


2
විසඳුම ආසන්නයි, නමුත් දීර් output කාලයක් තිස්සේ වෙන් කරන ලද නිමැවුමට නිසි වේලාවට මුද්‍රණය නොකරයි. එසේම, ඔබ බැක්ටික්ස් භාවිතා කරන අතර උපුටා දක්වා නොමැත $1. එය හොඳ විලාසිතාවක් නොවේ. සෑම විටම විචල්යයන් උපුටා දක්වන්න. ඊට අමතරව, ඔබ භාවිතා කරන්නේ echo, එය අතේ ගෙන යා නොහැකි ය. එය හරි, නමුත් සමහර පද්ධති මත නිසි ලෙස ක්‍රියා නොකරනු ඇත.
සර්ජි කොලොඩියාෂ්නි

මෙය පරීක්‍ෂා කිරීමෙන් පසු, ඔබ හරියටම නිවැරදි බව පෙනේ ... dateසෑම පේළියක්ම නැවත ඇගයීමට ලක් කළ හැකි ක්‍රමයක් ගැන ඔබ දන්නවාද , නැතහොත් එය බලාපොරොත්තු රහිතද?
රයන්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.