روشهای بیشماری برای انجام این کار هست، اما تمام آنها یا به ابزارهای در دسترس محدود میشوند، یا کُند هستند. ما چند نمونه را نشان خواهیم داد.
بیایید اول با روش آهسته قابل حمل شروع کنیم و با این نمونه آن را انجام بدهیم:
# POSIX while IFS= read -r line; do echo "$(date +%Y%m%d-%H:%M:%S) $line" done
و یکی دیگر که حتی کُندتر است:
awk '{system("printf \"`date +%T ` \">&2")}$0'
و سومی، که به طور جزئی سریعتر است، اما ممکن است بعضی از سطرهای ورودی را خُرد کند:
xargs -I@ -n1 date "+%T @"
اشکال واضح تمام مثالهای فوق آنست که ما در حال اجرای فرمان خارجی date برای هر سطر از ورودی میباشیم. اگر ما در هر دو ثانیه فقط یک سطر دریافت کنیم، شاید این پذیرفتنی باشد. اما اگر ما در حال تلاش برای مُهر تاریخ زدن به جریانی باشیم که در هر ثانیه سطرهای بسیاری تحصیل میکند، حتی ممکن است قادر به همگام شدن با نویسنده نباشیم.
روشهای متنوعی برای انجام این کار، بدون تولید پردازش فرزند(forking) به ازای هر سطر، وجود دارد، اما تمام آنها نیازمند ابزارهای غیر استاندارد یا پوستههای خاص، میباشند. Bash 4.2 میتواند آن را با printf انجام بدهد:
# Bash 4.2 while read -r; do printf "%(%Y%m%d-%H:%M:%S)T %s\n" -1 "$REPLY" done
مشخص کننده قالب %(...)T در bash نگارش 4.2 جدید است. شناسه -1 به او میگوید از زمان جاری به جای زمان عبور داده شده به عنوان شناسه، استفاده کند. برای جزئیات، صفحه man مربوط را ملاحظه نمایید.
یک روش دیگر، نوشتن یک perl یک سطری است:
perl -p -e '@l=localtime; printf "%04d%02d%02d-%02d:%02d:%02d ", 1900+$l[5], $l[4], $l[3], $l[2], $l[1], $l[0]'
مطمئن هستم شخصی با یک جایگزین 7 بایتی پیش خواهد آمد که همان کار را با استفاده از ترکیب دستوری جادویی پرل، که من هرگز قبلاً ندیدهام و نمیتوانم بفهمم، انجام میدهد، ....
ابزارهای دیگری مخصوصاً برای نشانهگذاری زمان فایلهای ثبت وقایع و مشابه، وجود دارد. یکی از آنها multilog از daemontools میباشد، اما قالب نشانهگذاری زمان آن TAI64N است که قابل خواندن انسانی نیست. دیگری ts از بسته moreutils میباشد.
پرسش و پاسخ 107 (آخرین ویرایش 2012-05-19 12:23:00 توسط GreyCat)