【问题标题】:Sort lines by timestamp in Emacs在 Emacs 中按时间戳对行进行排序
【发布时间】:2018-07-11 14:47:45
【问题描述】:

我有一个由多个线程写入的日志文件,因此不按顺序写入。 日志包含这样的条目:

[2018-07-11 15:30:39.139] [ddm.iolib.InputWorker] [debug] pop cmd from in queue...

[2018-07-11 15:30:39.140] [ddm.iolib.InputWorker] [debug] push cmd to out queue...

我想按时间戳对行进行排序。 我找到了在 bash 中排序的好答案:sort logfile by timestamp

这很好用,但我想在 Emacs 中对其进行排序。我尝试使用 sort-regexp-fields,但似乎我不够聪明,无法让它工作。 我尝试的是:

^.*\([0-9]+:[0-9]+:[0-9]+\.[0-9]+\]\).*$

作为记录说明符,\1 作为键。什么都没有排序。 请有人告诉我,我做错了什么? 除了 sort-regexp-fields,我也愿意接受其他可能性。

@Toby Speight 感谢您的提示。我理解这个问题,并且将来会尽量避免这样的问题。我只是在调试很多日志记录,这种排序在未来的很多情况下对我很有帮助。我是新来的,所以请接受我的道歉。

@Picaud Vincent 如果可以的话,我会投票。从未使用过 shell-command-on-region。实际上 sort-lines 对于这种情况就足够了,但是您的方法将来会很有用,因此您的答案被接受了。谢谢。

【问题讨论】:

  • 假设时间戳总是排在第一位,M-x sort-lines 会做你想做的事吗? (先输入C-x h,选择整个缓冲区)
  • 一个标准的 sort-lines 调用就足够了 - 这是使用 ISO-8601 时间戳的巨大优势!
  • 有关使用程序(例如 Emacs)的问题对于 Stack Overflow 来说是题外话,除非它们是特定于编程模式的;您可以通过EmacsSuper User 获得帮助。如果您的问题是关于 Emacs 编程的,那么请edit 包含您遇到问题的 Lisp 或 C 代码的minimal reproducible example

标签: emacs


【解决方案1】:

您可以将任何 bash 命令应用于选定区域:

请按以下步骤操作:

  1. 选择您的区域(或使用C-x h 选择整个缓冲区)

  2. 输入C-u M-|,Emacs会提示你输入你的shell命令,例如输入sort -k1 -r

就是这样! (注意,是M-| 而不是M-!

从 Emacs 文档中提取(您可以通过 C-h k M-| 获取):

M-|运行命令 shell-command-on-region(在 global-map 中找到), 这是“simple.el”中一个交互式编译的 Lisp 函数。

它绑定到 M-|, .

(shell-command-on-region START END COMMAND &optional OUTPUT-BUFFER

替换错误缓冲区显示-错误缓冲区区域-非连续-P)

在以区域为输入的下层 shell 中执行字符串 COMMAND。 通常在临时缓冲区'Shell 命令中显示输出(如果有) 输出';前缀 arg 表示用它替换区域。返回 COMMAND 的退出代码。

换句话说,M-| 运行 shell 命令并在“Shell 命令输出”缓冲区中显示输出。如果您希望此输出替换所选区域,您必须在 M-| 命令前添加前缀,这是我们的 C-u 命令(第 2 步)。


这里回答@Toby Speight 评论是一个例子。我将这些行用作初始缓冲区(您的question provided link

freeswitch.log:2011-09-08 12:21:07.282236 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda3525c0 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!
freeswitch.log:2011-08-08 13:21:07.514261 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda354460 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!
freeswitch.log:2011-06-04 16:21:08.998227 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda356300 in queue 0x7f2ce8005990, no more room! windex == rindex == 58! 
freeswitch.log:2011-09-08 12:21:10.374238 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda3581a0 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!

我输入:C-x h C-u M-| sort -k1 -r <RET>(其中<RET> 代表“返回”键盘键),结果我的缓冲区现在包含:

freeswitch.log:2011-09-08 12:21:10.374238 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda3581a0 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!
freeswitch.log:2011-09-08 12:21:07.282236 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda3525c0 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!
freeswitch.log:2011-08-08 13:21:07.514261 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda354460 in queue 0x7f2ce8005990, no more room! windex == rindex == 58!
freeswitch.log:2011-06-04 16:21:08.998227 [ERR] ftdm_queue.c:136 Failed to enqueue obj 0x7f2cda356300 in queue 0x7f2ce8005990, no more room! windex == rindex == 58! 

【讨论】:

  • 虽然这可能是解决问题的一个有价值的提示,但一个好的答案也可以证明解决方案。请edit 提供示例代码来说明您的意思。或者,考虑将其写为评论。
  • @TobySpeight 感谢您的反馈。但是我不确定是否能很好地理解您的要求:没有代码,因为解决方案只是键入 C-x h C-u M-|在 Emacs 下排序 -k1 -r 。我们本可以为此定义一个 Emacs-lisp 函数,但这肯定是一个矫枉过正的解决方案。为了更清楚起见,我添加了一个完整的使用示例。
  • 事实上,一系列交互式击键实际上是Super UserEmacs 答案,而不是Stack Overflow 答案。当然,问题可能出在错误的网站上——我已经做出了相应的评论。
  • @TobySpeight 我以后会尽量避免此类问题/答案。我明白这个问题。
【解决方案2】:

尽管 Picaud Vincent 的回答描述了 emacs 用户在他们的工具带中拥有的一种重要方法,但我想为后代记录 cmets 的答案,因为它很简单,并且以最少的麻烦准确地解决了 OP 的问题:

  • 标记适当的区域(可能用C-x h 标记整个缓冲区)。
  • M-x sort-lines

【讨论】:

    【解决方案3】:

    可以使用sort-regexp-fields,但鉴于时间戳位于行首(并且您使用 ISO 8601 格式的时间戳),这意味着它们可以很好地排序只需sort-lines。假设你想对整个缓冲区进行排序,那就是

    (sort-lines nil (point-min) (point-max))
    

    您使用的方法将仅匹配时间戳的 时间 部分,因此您最终可能会将不同的日期混合在一起。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多