【问题标题】:Unable to read the timestamp of Zsh history无法读取 Zsh 历史的时间戳
【发布时间】:2009-04-29 20:27:56
【问题描述】:

问题:了解以下时间戳

1241036430

在 ~/.history

: 1241036336:0;vim ~/.zshrc
: 1241036379:0;vim ~/bin/HideTopBar
: 1241036421:0;ls
: 1241036430:0;cat ~/.history

当我有

setopt EXTENDED_HISTORY
HISTFILE=~/.history

在 .zshrc 中。

如何读取时间戳?

【问题讨论】:

  • 我很好奇第二个整数(看起来总是 0)是什么。这个数字代表什么?

标签: timestamp zsh


【解决方案1】:

使用 awk 转换时间戳

如果您想读取文件本身,与grep 或任何其他过滤器一起使用,您需要转换时间戳。

我制作了这个脚本,并将它保存在我的/usr/local/bin 中,它适用于 bashzshell

脚本 uhistory.awk 在 /usr/local/bin/uhistory.awk

#!/usr/bin/awk -f
{ 
        if (match($0,/^#/)) # bash
        {
                nlin++
                #adata="@"substr($0,2) 
                #printf("%s ", adata)
                cmdata = "date -d \"@" substr($0,2) "\" +\"%F %H:%M:%S\"" 
                cmdata | getline datado
                close(cmdata)
                printf("%d %s ", nlin, datado)
        }
        else
        if (match($0,/^:/)) # zshell
        {
            nlin++
            split($0, arr, ":|;")
            cmdata = "date -d \"@" substr(arr[2],2) "\" +\"%F %H:%M:%S\"" 
            cmdata | getline datado
            close(cmdata)
            printf("%d : %s ; %ss % ", nlin, datado, arr[3])
            for (i in arr)
            {
                if (i < 4)
                    continue
                printf("%s ", arr[i])
            }
            printf("\n")
        }
        else
        {
            print $0
        }
}

用法:您可以将历史记录通过过滤器。假设zsh 的历史文件具有以下格式:

:timestamp:duration;commands

没有 uhistory.awk 过滤器将是:

% head ~/.config/zsh/zhistfile

: 1570482839:0;la
: 1570482839:0;cd zsh
: 1570482839:0;ls
: 1570482839:1;cat verybigaliasfile.txt
: 1570482839:0;alias
: 1570482839:0;ls -la
: 1570482839:0;vi .zshrc
: 1570482839:0;alias

使用 uhistory.awk 过滤器,它将显示为:

% head ~/.config/zsh/zhistfile | uhistory.awk | grep alias

4 : 2019-10-07 18:13:59 ; 1s % cat verybigaliasfile.txt
5 : 2019-10-07 18:13:59 ; 0s % alias 
9 : 2019-10-07 18:13:59 ; 0s % alias 

但如果您的使用不涉及处理文件本身,那么您真正需要的只是一个别名。

将此行添加到您的 .zsh_aliases 或您为别名设置的其他位置。

alias history='fc -il 1'

或来自fc 命令的其他选项。检查man zshbuiltins


更好的是使用相同的命令,所以如果您想在最后添加另一个键/选项就不会造成混淆。在这种情况下,我建议:

alias history='history -i'

当然你也可以只管结果,例如:

% history | grep alias

4   2019-10-07 18:13:59  cat verybigaliasfile.txt
5   2019-10-07 18:13:59  alias 
9   2019-10-07 18:13:59  alias 

在这种情况下,duration 不会出现,但其余部分相同。

【讨论】:

  • 当您想 grep 历史文件时,这是如何工作的?
  • 我重写了整个答案,现在我解释了简单的别名加grep,以及自定义过滤器uhistory.awk
  • 谢谢,你的脚本真的很有帮助
  • 很高兴它为您服务。
【解决方案2】:

这个名为localtime 的简单util 是读取带有时间戳的文件的黄金:

#!/usr/bin/perl
# http://perl.plover.com/classes/mybin/samples/source/localtime

if ($ARGV[0] eq '-f') {
  *show_localtime = \&show_localtime_list;
  shift;
}

if (@ARGV) {
  for (@ARGV) {
    print show_localtime($_), "\n";
  }
} else {
  while (<>) {
    s/^(\d+)/show_localtime($1)/e;
    print;
  }
}


sub show_localtime {
  my $t = shift;
  scalar localtime $t;
}

sub show_localtime_list {
  my $t = shift;
  my @a = localtime $t;
  "@a\n"
}

它处理了很多情况,并且似乎理解以秒和微秒为单位的时间戳等。

$ localtime < ~/.histfile
<snip>
: Sat Sep 17 05:55:17 2016:0;cat localtime

【讨论】:

  • 能不能把这个功能用于其他的历史文件,而不仅仅是Zsh的那个?
  • 是的,它通常可以正常工作。它只是查找第一个数字字符串并将其转换为人类可读的日期。
【解决方案3】:

试试history -d。或者只需输入 history - 并按 control-D 即可获得所有各种选项:

% history -
-D  -- print elapsed times
-E  -- dd.mm.yyyy format time-stamps
-d  -- print time-stamps
-f  -- mm/dd/yyyy format time-stamps
-i  -- yyyy-mm-dd format time-stamps
-m  -- treat first argument as a pattern
-n  -- suppress line numbers
-r  -- reverse order of the commands

【讨论】:

  • 感谢您的解释!
  • 了解到 ctrl-D 将提供所有选项的新事物。谢谢你!!
  • “不工作”是什么意思——history -dhistory - 上的制表符完成?尝试时会发生什么?
  • 如果这不起作用,请检查 history 的别名(我的是 fc -l 1,它不会采取任何进一步的选择)。 zsh history 内置调用 fc -l,您可以将其与上述选项一起使用:例如,fc -l -d
  • 不起作用并给出这个:fc: event not found: -d
【解决方案4】:

您可以使用取自an answer on the zsh mailing list 的这一单行代码以人类可读的时间戳显示整个历史记录:

perl -lne 'm#: (\d+):\d+;(.+)# && printf "%s :: %s\n",scalar localtime $1,$2' $HISTFILE

我建议将输出通过管道传输到寻呼机(例如less)以使其更具可读性。

【讨论】:

    【解决方案5】:

    附录:您也可以使用history 命令本身来翻译保存的历史文件中的时间戳:

    Nicholas Riley 解释的history 命令的选项同样适用于保存的历史文件,因此history -d &lt; historyfile(或任何其他选项)可以很好地转换时间戳。

    如果您使用多个历史文件,这会派上用场 - 我已设置 zsh 为每个 pty 保留一个历史文件,以避免混淆同一系统上并行运行的 shell 的历史(因为通常每个窗口/屏幕/...都是特定于某个任务的,因此从正常使用中出现的历史最终会带有某种主题)。

    【讨论】:

    • history -d &lt; historyfile 对我不起作用。它只是打印当前历史记录,而不是文件给出的历史记录。
    【解决方案6】:
    : 1241036430:0;cat ~/.history
    
    ‘: <beginning time>:<elapsed seconds>;<command>’.
    

    extendedhistory - 以秒为单位节省时间。开始时间是从纪元开始的。

    来源:http://zsh.sourceforge.net/Doc/Release/Options.html#index-EXTENDEDHISTORY

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-14
      • 2015-01-06
      • 2020-07-04
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 2021-09-03
      相关资源
      最近更新 更多