이전 bash 명령의 오타를 영구적으로 수정하는 방법은 무엇입니까?

이전 bash 명령의 오타를 영구적으로 수정하는 방법은 무엇입니까?

Bash 대화형 셸에 명령을 입력할 때 철자 오류가 발생하는 것은 드문 일이 아닙니다. 나는 잘못된 명령으로 인해 bash 기록이 오염되어 나중에 실수로 다시 실행되는 일이 없도록 bash 기록의 오타를 수정할 수 있기를 원합니다. 특히 마지막 명령을 편집하고 싶습니다.

가지다상당히 숫자 ~의 질문어떻게 물어보세요예방하다실수로 bash 기록을 편집했습니다. 나는 그 반대를 원한다: 나는 원한다분명히기록을 편집합니다.

참조 질문의 일부 설명을 바탕으로 다음을 시도했습니다.

$ echo foo

Up다음과 같이 변경하려면 누르세요 .

$ echo foobar

누르지 Down만 아무 작업도 수행되지 않습니다. 그런 다음 누르면 Enter수정된 명령이 실행되고 둘 다 유지됩니다.

echo foo
echo foobar

내 역사에.

기록 항목을 수동으로 삭제할 수 있다는 것을 알고 있지만 history -d편리하게 사용할 수 있는 좋은 방법은 고안하지 못했습니다. 마지막 기록 항목을 무조건 삭제하는 쉘 함수를 만들고 싶지 않습니다. 왜냐하면 Up마지막 항목을 로드하여 수정할 수 있기를 원하기 때문입니다. 수정한 다음 마지막에서 두 번째 기록 항목을 삭제할 수 있지만 이는 투박한 느낌이 들며 나중에 추가 단계를 수행해야 한다는 것을 기억하거나 이 단계의 실행을 일시적으로 일시 중지해야 한다는 것을 기억해야 하기 때문에 장기 실행 명령의 경우 특히 짜증납니다. 계속하다.

내가 원하는 것은:

  • 이상적으로 내가 할 수 있는 작업은 를 누르고 Up이전 명령을 수정한 다음 특수 키 바인딩을 누르거나 명령줄에 마법 플래그를 추가하여 실행 시 기록 항목을 대체하는 것입니다.

  • 실행 시 기록 항목을 덮어쓰는 기록에서 명령을 검색하고 편집하기 위해 다른 키 시퀀스를 누르는 것도 허용됩니다(Ctrl+R과 유사).

  • 강한마지막에서 두 번째 기록 항목을 삭제하는 셸 기능은 허용되지만 이상적이지는 않습니다.

나는 다른 사람들도 실수를 했을 것이고, 이러한 명령이 그들의 역사를 더럽힐 때 똑같이 짜증을 냈을 것이라고 생각합니다. 다른 사람들은 무엇을 하나요?

답변1

옵션 #1 - 수동

~/.bash_history편집기에서 파일을 열고 파일 vim에 원하는 대로 변경한 후 저장하면 됩니다.

$ vim ~/.bash_history

편집하기 전에 현재 터미널 기록도 이 파일에 커밋되어 있는지 확인하세요.

$ history -a

기록 파일은 이 환경 변수가 가리키는 위치에 있습니다.

$ echo $HISTFILE
/Users/user1/.bash_history

옵션 #2 - HSTR

~/.bash_history보다 체계적인 방식으로 파일을 관리하는 데 사용할 수 있는 HSTR이라는 CLI 도구가 있습니다 . 이것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하고 수정하여 명령을 다시 실행할 수 있습니다. 이전 명령을 대화식으로 편집할 수 있는 것만큼 좋지는 않지만 내 요구 사항에는 충분하다고 생각합니다.

관련 정보