【问题标题】:Bash history without line numbers [closed]没有行号的 Bash 历史记录[关闭]
【发布时间】:2011-10-29 22:06:55
【问题描述】:

bash history 命令非常酷。我明白为什么它显示行号,但是有没有办法可以调用历史命令并取消行号?

这里的重点是使用历史命令,所以请不要回复cat ~/.bash_history

电流输出:

  529 man history
  530 ls
  531 ll
  532 clear
  533 cd ~
  534 history

Historical graphic source.

期望的输出:

man history
ls
ll
clear
cd ~
history

Historical graphic source.

感谢大家的出色解决方案。 Paul's 是最简单的,因为我的 bash 历史大小设置为 2000,所以对我有用。

我还想分享我今天早上发现的一篇很酷的文章。我现在正在使用它有几个不错的选项,比如将重复条目排除在 bash 历史记录之外,并确保多个 bash 会话不会覆盖历史记录文件:http://blog.macromates.com/2008/working-with-history-in-bash/

【问题讨论】:

  • 请问为什么排除cat ~/.bash_history
  • @flow2k 因为这是保存的历史记录,(从最后一个 shell 退出),而不是当前历史记录!
  • @anthony 你可以先运行history -a 来保存你当前的历史记录

标签: linux bash


【解决方案1】:

试试这个:

$ history | cut -c 8-

【讨论】:

  • 我们可以通过管道输入history 命令的输出而不是读取文件吗?
  • man cut。它正在删除history 命令每行输出的前 7 个字符。只有当数量超过 99,999 时,它才会出现问题,这是我从未见过的(而且我经常使用 shell)。但是,如果您对此感到担忧:history | sed 's/^ *[0-9]* *//'
  • 我认为@Paul R 的解决方案是我所需要的。起初我没有意识到历史命令是用空格填充行号,现在cut 语法更有意义:) 感谢@Keith Thompson 为您提供的解决方案,该解决方案适用于 > 100k 历史记录。
  • @cwd:如果您的历史记录中有 100,000 条命令,那么是时候离开键盘回家了。如果您已经在家,请出去。 8-)}(是的,我知道历史可以跨会话保留。)
  • 好吧,HISTSIZE 默认为最大 500 或 1000,如果你不更改它cut -c 8- 将永远不会失败
【解决方案2】:

awk 可以帮忙:

history|awk '{$1="";print substr($0,2)}'

This answer 历史悠久,可能会失败。

【讨论】:

  • 哈哈,谢谢-substr 简单多了,我一直用history | awk '{for (i=2;i<=NF;i++) printf("%s ", $i);print("\r")}' 为我的!!
【解决方案3】:

如果您愿意切换到 zsh 而不是 bash,那么 zsh 本身就支持这一点(以及历史格式化的其他选项)

zsh> fc -ln 0

(见https://serverfault.com/questions/114988/removing-history-or-line-numbers-from-zsh-history-file

【讨论】:

  • 实际上fc 也是一个bash 内置函数。唯一的区别是第一行是1,所以应该是fc -ln 1
  • 虽然其他命令有效,并且此命令未使用 history (OP 特别要求),但我赞成这个答案的简单性。尝试记住 cut 的语法对我来说可能很笨拙,但这对我来说就像 ls -hal 一样容易记住
【解决方案4】:
history -w /dev/stdout

来自history --help的输出:

-w 将当前历史写入历史文件

它将当前历史记录写入指定文件 - 在这种情况下为/dev/stdout

【讨论】:

  • 这实际上是实践中最容易记住的!干净简单 - 再加上无需了解 regex/sed/awk 的知识 :-)
  • 如果您不是 root,则此方法不起作用,并且您使用 su 切换到该用户,因为 root 将保留 /dev/stdout 的所有权,请参阅这个非常好的答案了解更多信息详情:unix.stackexchange.com/questions/38538/…。对于用户,history -w /dev/tty 有效,但它与stdout完全相同。
【解决方案5】:

我迟到了,但更短的方法是在您的 ~/.bashrc~/.profile 文件中添加以下内容:

HISTTIMEFORMAT="$(echo -e '\r\e[K')"

来自 bash manpage:

 HISTTIMEFORMAT
              如果此变量已设置且不为空,则将其值用作
              strftime(3) 的格式字符串以打印相关的时间戳
              每个历史记录条目都由内置的历史记录显示。如果
              这个变量被设置,时间戳被写入历史
              文件,以便它们可以在 shell 会话中保留。这使用
              用于区分时间戳的历史注释字符
              其他历史线。

使用此功能,一个聪明的技巧在于使变量“打印”一个回车符 (\r) 并清除该行(ANSI 代码 K)而不是实际的时间戳。

【讨论】:

  • 简单一点,使用更晦涩的语法:HISTTIMEFORMAT=$'\r\e[K'
  • 还有一个选项:HISTTIMEFORMAT=$'\r\e[K' history
【解决方案6】:

或者,您可以使用 sed:

history | sed 's/^[ ]*[0-9]\+[ ]*//'

使用别名,您可以将其设置为您的标准(将其粘贴在您的 bash_profile 中):

alias history="history | sed 's/^[ ]*[0-9]\+[ ]*//'"

【讨论】:

  • \+ 在基本正则表达式中不符合 POSIX。如果您的sed 不支持非标准的\+ 扩展,请使用\{1,\}
【解决方案7】:

尽管使用 -c 选项进行剪切适用于大多数实际目的,但我认为将管道历史记录到 awk 将是一个更好的解决方案。例如:

history | awk '{ $1=""; print }'

history | awk '{ $1=""; print $0 }'

这两种解决方案都做同样的事情。历史的输出被馈送到 awk。然后,Awk 将第一列清空,该列对应于历史命令输出中的数字。这里 awk 更方便,因为您不必关心输出的数字部分中的字符数。

print $0 等价于print,因为默认是打印行上出现的所有内容。键入print $0 更明确,但您选择哪一个取决于您。如果您使用 awk 打印文件,print $0 和简单的 print 与 awk 一起使用时的行为会更加明显(cat 会比 awk 更快地键入,但这是为了说明一点)。

[Ex] 使用 awk 显示带有 $0 的文件的内容

$ awk '{print $0}' /tmp/hello-world.txt
Hello World!

[Ex] 使用 awk 显示文件内容,无需显式 $0

$ awk '{print}' /tmp/hello-world.txt
Hello World!

[Ex] 历史行跨越多行时使用 awk

$ history
   11  clear
   12  echo "In word processing and desktop publishing, a hard return or paragraph break indicates a new paragraph, to be distinguished from the soft return at the end of a line internal to a paragraph. This distinction allows word wrap to automatically re-flow text as it is edited, without losing paragraph breaks. The software may apply vertical whitespace or indenting at paragraph breaks, depending on the selected style."

$ history | awk ' $1=""; {print}'
 clear
 echo "In word processing and desktop publishing, a hard return or paragraph break indicates a new paragraph, to be distinguished from the soft return at the end of a line internal to a paragraph. This distinction allows word wrap to automatically re-flow text as it is edited, without losing paragraph breaks. The software may apply vertical whitespace or indenting at paragraph breaks, depending on the selected style."

【讨论】:

    【解决方案8】:

    history 命令没有抑制行号的选项。您将不得不按照每个人的建议组合多个命令:

    示例:

    history | cut -d' ' -f4- | sed 's/^ \(.*$\)/\1/g'
    

    【讨论】:

    • 如果您要通过sed 运行它,那么初始剪切是多余的 - 只需将其添加到表达式中即可。
    【解决方案9】:
    $ hh -n
    

    您可能想尝试https://github.com/dvorka/hstr,它允许使用(可选)基于度量的排序对 Bash 历史进行“建议框样式”过滤,即它在向前和向后方向上都更加高效和快速:

    它可以很容易地绑定到 Ctrl-r 和/或 Ctrl-s

    【讨论】:

      【解决方案10】:

      您可以使用命令cut来解决它:

      从 STDIN 或文件中删除字段。

      • 剪掉 STDIN 每一行的前十六个字符: cut -c 1-16

      • 删除给定文件每行的前十六个字符: cut -c 1-16 file

      • 删除从第三个字符到每行末尾的所有内容: cut -c3-

      • 删去每行的第五个字段,使用冒号作为字段分隔符(默认分隔符是制表符): cut -d':' -f5

      • 删除每行的第 2 和第 10 字段,使用分号作为分隔符: cut -d';' -f2,10

      • 删除每行的第 3 到第 7 字段,使用空格作为分隔符: cut -d' ' -f3-7

      【讨论】:

        【解决方案11】:

        我知道我迟到了,但这更容易记住:

        cat ~/.bash_history
        

        【讨论】:

        • 没错,但是OP的第二行:“这里的重点是使用history命令,所以请不要回复cat ~/.bash_history”
        • 太好了。作为我使用过的较低级别的替代方案。
        • 另外,cat ~/.bash_history 只会打印出该文件的内容。仍然在内存中的命令呢?如果您希望它真正包含所有内容,则需要先history -w
        【解决方案12】:

        如果您尝试将不带行号的历史记录发送到文件中并希望获得该文件以供以后参考,请阅读以下内容:

        history | sed 's/^[ ]*[0-9]\+[ ]*//' >>history.txt
        

        上述命令会将您的历史记录内容读入一个名为 history 的文本文件中。这将允许您在项目进行时拥有不同的版本。

        我喜欢它,因为它可以帮助我在执行 bash 脚本时简化自动化 (wink)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-01-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-13
          • 1970-01-01
          • 2012-12-21
          • 2010-09-25
          相关资源
          最近更新 更多