我有一个格式的文件
47 2013-05-01 1367406011 2 30 15
47 2013-05-01 1367406388 1 29 14
43 2013-05-01 1367407469 1 26 12
42 2013-05-01 1367407489 1 25 11
42 2013-05-01 1367407810 1 24 11
39 2013-05-01 1367409056 1 22 9
41 2013-05-01 1367409610 1 22 9
36 2013-05-01 1367411409 1 22 9
34 2013-05-01 1367412388 1 20 9
32 2013-05-01 1367413208 1 19 9
第三列是自纪元以来测量的时间(以秒为单位)。我希望能够以更接近日常时钟时间的方式查看时间,并且正在寻找最简单的方法来转换文件中的每一列。
执行转换的最有效方法是什么?(我在 OSX 上)
答案1
如果您在执行此操作的机器上安装了 Perl,并且文件中的每一行都与问题中的示例格式相同,则以下命令行将发出一个文件版本,其中 Unix 时间替换为人类可读的值:
cat source-file | perl -pe's@(^\d+ [\d-]+ )(\d+)@$1 . scalar(localtime($2))@e;'
我自己是一个 Emacs 用户,但是我从 vim 手册中了解到,您可以通过执行以下操作将此命令应用于当前缓冲区的内容:
1,$!perl -pe's@(^\d+ [\d-]+ )(\d+)@$1 . scalar(localtime($2))@e;'
答案2
在 Vim 中,这个快速宏可以完成这个工作:
qq " start recording
0 " go to first column
2W " go to time column
"mciw " put time in register m and replace it…
<C-r>=strftime("%T", @m)<CR> " …with localized time
<Esc> " exit insert mode
q " stop recording
录制宏后,选择所有要翻译的行,然后执行以下操作:
:'<,'>norm @q
如果这些行与你不想触碰的其他行交错,你可以使用该:g[lobal]
命令执行宏仅有的在符合某些模式的行上:
:g/2013-05/norm @q
参考:
:h :normal
:h :global
和
:h strftime()
了解日期格式的想法。
使用该宏,您的样本立即变成:
47 2013-05-01 13:00:11 2 30 15
47 2013-05-01 13:06:28 1 29 14
43 2013-05-01 13:24:29 1 26 12
42 2013-05-01 13:24:49 1 25 11
42 2013-05-01 13:30:10 1 24 11
39 2013-05-01 13:50:56 1 22 9
41 2013-05-01 14:00:10 1 22 9
36 2013-05-01 14:30:09 1 22 9
34 2013-05-01 14:46:28 1 20 9
32 2013-05-01 15:00:08 1 19 9