Linux 如何将日期字符串添加到连续写入的日志文件的每一行

Linux 如何将日期字符串添加到连续写入的日志文件的每一行,linux,bash,string,logging,csh,Linux,Bash,String,Logging,Csh,有一个长时间运行的程序,可以连续写入日志文件——在不考虑任何缓冲问题的情况下,如何能够使用linux脚本向写入该文件的每一行添加一个日期字符串 我会这样想象: tail -f logfile | ADD_DATE_TO_EACH_LINE > logfile2 输入应该是这样的: abc def ghi jkl 输出应类似于: 2011-06-16 18:30:59 abc 2011-06-16 18:31:00 def 2011-06-16 18:35:21 ghi 2011-06-

有一个长时间运行的程序,可以连续写入日志文件——在不考虑任何缓冲问题的情况下,如何能够使用linux脚本向写入该文件的每一行添加一个日期字符串

我会这样想象:

tail -f logfile | ADD_DATE_TO_EACH_LINE > logfile2
输入应该是这样的:

abc
def
ghi
jkl
输出应类似于:

2011-06-16 18:30:59 abc
2011-06-16 18:31:00 def
2011-06-16 18:35:21 ghi
2011-06-16 18:40:15 jkl

您是否可以将长时间运行的程序配置为将其输出写入标准输出而不是日志文件?在这种情况下,通过管道将输出传输到脚本将很容易,该脚本首先写入当前时间戳,然后写入条目

如果不可能,则可以定期(例如,每秒)读取日志文件内容,将每行复制到另一个文件(添加当前时间戳),然后删除日志文件。但是,这可能会导致在读取和删除文件之间写入的日志文件条目丢失:(

Try

tail -f logfile | while read line; do echo `date` "$line" ; done
使用perl:

command 2>&1 | perl -pe 'print scalar(localtime()), " ";'
目瞪口呆:

command 2>&1 | awk '{ print strftime(), $0; fflush() }'

命令
替换为
tail-f日志文件
,用于您的特定示例。或者,您可以将原始程序的stdout/stderr重定向到上面的管道。

有点长,但我想到的是:

tail -f logfile | sed -u 's/%/%%/g' | xargs -I {} date +"%Y-%m-%d %H:%M:%S {}"
你可以试试这个

cat /etc/motd | xargs -d"\n" -I {} date +"%Y-%m-%d %H:%M:%S {}"
示例输出:

2013-02-26 15:13:57 2013-02-26 15:13:57 The programs included with the Debian GNU/Linux system are free software; 2013-02-26 15:13:57 the exact distribution terms for each program are described in the 2013-02-26 15:13:57 individual files in /usr/share/doc/*/copyright. 2013-02-26 15:13:57 2013-02-26 15:13:57 Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent 2013-02-26 15:13:57 permitted by applicable law. 2013-02-26 15:13:57 2013-02-26 15:13:57 Debian GNU/Linux系统附带的程序是自由软件; 2013-02-26 15:13:57各节目的确切分配条款见 2013-02-26 15:13:57/usr/share/doc/*/版权中的单个文件。 2013-02-26 15:13:57 2013-02-26 15:13:57 Debian GNU/Linux在某种程度上绝对没有保修 2013-02-26 15:13:57适用法律允许。
或者你可以使用python

cat/dev/uradom|python-c“来自未来导入打印函数;导入系统;导入日期时间;映射(lambda x:print(datetime.datetime.now(),x),[sys.stdin.readlines()中的行对应行]”

或者使用gnu屏幕

screen-a ls-lh-L-U-X命令
首先,您需要在~/.screenrc上启用日志记录和时间戳

logfile /tmp/screen-%S-%n.log
logtstamp on

一个工具正是为了这个目的而存在的,它是
ts
(请参见
man-ts

例如,使用日志文件:

tail -f logfile | ts '%Y-%m-%d %H:%M:%S'
当然,也可以与任何在标准输出上编写的软件配合使用:

./blabla | ts '%Y-%m-%d %H:%M:%S'
如果需要,您可以使用
%.S
而不是
%S

添加亚秒精度。我看到一个建议,如果时效性很重要,应该避免从BASH调用其他程序,并使用内置的:

printf '%(%F %T)T\n'
%T是来自AFAICT的
日期
(请参见
人工日期
)的相同格式字符串。 例如:

将输出:

2021-03-28 1616894012 Err, Miss Crabapple, I just ate my worm!

我刚刚注意到关于该链接的一条评论中有一条建议可以使用。

+1但是只有一条注释:使用
date+%y-%m-%d%H:%m:%S“
而不是简单地使用
date
将得到他期望的确切输出;您也可以在最后将重定向添加到输出文件。(实际上是两条注释):)谢谢,这很有效。如果您将
符号添加到
$line
中,shell将不会将
*
符号扩展到目录内容;)此解决方案的问题是:当“while read line”循环的输入缓冲区过大时,某些行将被截断。我无法将程序配置为记录到标准输出,因为它是(resp.可以用作)一个交互式程序。但在我看来,实际执行
tail-f
与直接写入stdout差不多。实际上,我正在寻找“先写入当前时间戳,然后写入条目的脚本”。然后可以使用FIFO。该程序会将所有内容写入命名管道(FIFO)您可以同时从中读取、添加日期并写入真实的日志文件。这是一个非常好的解决方案。但是
sed-u的/%/%/g'
用于什么?
%
符号对
xargs
有特殊意义吗?@bmk此方法将整行放入
date
的格式字符串中,其中
%
有一个特殊的含义。例如,如果日志中的行包含
%Y
,那么它将被年份替换,但是使用
sed
将其更改为
%Y
将正确地输出
%Y
。我还有一句话:如果有单引号(
)在输入流中,
xargs
以以下错误消息终止:
xargs:unmatched single quote;默认情况下,除非使用-0选项,否则引号对xargs是特殊的,因此我将命令更改为
tail-f logfile | sed-u's/%/%/g'| tr“\n”“\0”| xargs-0-I{}日期+%Y-%m-%d%H:%m:%s{}“
。这个答案的好处是,它不会为每一行生成新的日期进程,但两者都很好。
perl-pne
?您不需要
-n
以及
-p
。谢谢!我真的不懂perl。我只是从互联网上剪切并粘贴了其他crud.)我上一次真正使用perl是在十多年前!我通常使用上面gawk提供的答案,但也包括perl答案,以防OP不在linux上。@StevePrentice当我执行第一个命令时,它会挂起。我正在运行
tail-f test-text.rtf2>&1|perl-pe“打印标量(localtime()),”;”>test text.rtf
知道为什么吗?@Vouze您可以使用中间的
sed
来解决这个问题,或者实际上可以代替
sed's/%/%/g'/etc/motd | xargs…
ts
在Ubuntu上的软件包
moreutils
中,类似的,通过
sudo-apt-install-moreutils
安装。
2021-03-28 1616894012 Err, Miss Crabapple, I just ate my worm!