如何永久纠正上一个 bash 命令中的拼写错误?

如何永久纠正上一个 bash 命令中的拼写错误?

在 bash 交互式 shell 中输入命令时出现拼写错误的情况并不罕见。我希望能够纠正 bash 历史记录中的拼写错误,以便错误的命令不会污染它并导致我稍后意外地重新执行它。特别是,我想编辑最后一个命令。

相当 A 数字 问题询问如何防止不小心编辑了 bash 历史记录。我想要相反的:我想要明确地编辑历史记录。

根据参考问题的一些解释,我尝试这样做:

$ echo foo

Up,将其更改为:

$ echo foobar

Down,但这没有任何作用,如果我然后按Enter,它将执行修改后的命令并保留两者

echo foo
echo foobar

在我的历史中。

我知道我可以使用 手动删除历史记录条目history -d,但我还没有设计出一种方便使用它的好方法。我不想创建一个 shell 函数来无条件删除最后一个历史条目,因为我仍然希望能够使用它Up来加载最后一个条目,以便我可以更正它。我可以进行更正,然后删除倒数第二个历史条目,但这感觉很笨拙,而且对于长时间运行的命令来说尤其烦人,因为我要么需要记住稍后执行额外的步骤,要么需要暂时暂停执行这些步骤,然后继续。

我想要的是:

  • 理想情况下,我希望能够做的是按Up,对之前的命令进行更正,然后按一些特殊的键绑定或向命令行添加一些魔术标记,以使其在执行时替换历史记录条目。

  • 也可以接受的是按其他按键序列从历史记录中检索和编辑命令(类似于 Ctrl+R),该命令在执行时会覆盖历史记录条目。

  • A强壮的删除倒数第二个历史条目的 shell 函数是可以接受的,但并不理想。

我想其他人肯定也会犯错,并且当这些命令污染他们的历史时也会同样感到恼火。其他人做什么?

答案1

选项 #1 - 手动

我只需~/.bash_history在编辑器中打开该文件vim,然后对该文件进行所需的任何更改并保存。

$ vim ~/.bash_history

在编辑之前,请确保您当前的终端历史记录也已提交到此文件:

$ history -a

请记住,您的历史文件位于此环境变量所指向的位置:

$ echo $HISTFILE
/Users/user1/.bash_history

选项 #2 - HSTR

有一个名为 HSTR 的 CLI 工具,您可以使用它来管理您的~/.bash_history以更系统的方式管理文件。这HSTR 主要网站是视频和使用它的详细信息。

它还提到了这个简介:

HSTR 还可以管理您的命令历史记录(例如,您可以删除过时的或包含敏感信息的命令)或为您最喜欢的命令添加书签。

有关更多信息,请参阅完整文档:HSTR 文件

参考

答案2

高铁看起来很吸引人,但结果对我来说有点太重了。

相反,我编写了自己的 bash 函数:

# Removes the last command from the history that matches the given search
# string and re-executes it using the given replacement string.
#
# Usage:
#   historysub SEARCH [REPLACEMENT]
#   historysub -d SEARCH
#
#   REPLACEMENT may be omitted to remove SEARCH from the executed command.
#
#   -d removes the last command matching SEARCH from the history without
#   executing a new command.
historysub()
{
  local delete=0
  local usage=0
  local OPTIND=1
  while getopts ":hd" option; do
    case "${option}" in
      d) delete=1 ;;
      h) usage=1 ;;
      ?) usage=2 ;;
    esac
  done
  shift $((OPTIND - 1))

  local search="${1-}"
  local replacement="${2-}"

  usage_text=
  usage_text+="Usage: ${FUNCNAME[0]} SEARCH [REPLACEMENT]\n"
  usage_text+="       ${FUNCNAME[0]} -d SEARCH\n"

  if (( usage )); then
    echo -e "${usage_text}"
    return $(( usage - 1 ))
  fi

  if [[ -z "${search}" ]]; then
    echo -e "${usage_text}" >&2
    return 1
  fi

  # RE to parse the `history` output.
  local hist_re='^[ \t]*([0-9]+)[ \t]+(.+)$'

  local hist_full
  hist_full=$(HISTTIMEFORMAT="" history)

  # We don't want the search string to accidentally match against history
  # numbers, so split the `history` output so that we can search against just
  # the commands.
  local hist_nums hist_cmds
  hist_nums=$(sed -E "s/${hist_re}/\1/" <<< "${hist_full}")
  hist_cmds=$(sed -E "s/${hist_re}/\2/" <<< "${hist_full}")

  # Find the last matching history entry (excluding ourself).
  local matches last_match
  matches=$(grep -nF -- "${search}" <<< "${hist_cmds}")
  last_match=$(grep -vF -- "${FUNCNAME[0]}" <<< "${matches}" | tail -n 1)

  if [[ -z "${last_match}" ]]; then
    echo "${FUNCNAME[0]}: \"${search}\" not found." >&2
    return 1
  fi

  # RE to parse the `grep -n` output.
  local line_re='^([0-9]+):[ \t]*(.+)$'

  # Note that the line number and the history number might not be the same, so
  # we need to retrieve the original history number.
  local line_num hist_cmd hist_num
  line_num=$(sed -E "s/${line_re}/\1/" <<< "${last_match}")
  hist_cmd=$(sed -E "s/${line_re}/\2/" <<< "${last_match}")
  hist_num=$(tail -n +${line_num} <<< "${hist_nums}" | head -n 1)

  history -d "${hist_num}"
  if (( delete )); then
    echo "Removed: ${hist_cmd}"
    return 0
  fi

  local cmd="${hist_cmd/${search}/${replacement}}"
  echo "${cmd}"

  # Add the new command to the history.
  history -s -- "${cmd}"
  eval -- "${cmd}"
}

所以现在我可以运行historysub TYPO CORRECTION并进行更正来重新执行命令。它不如能够交互式编辑旧命令那么好,但我认为它应该足以满足我的需求。

相关内容