Cách xóa lệnh cuối cùng (hoặc lệnh hiện tại để nhận tiền thưởng) khỏi lịch sử zsh


13

Chắc chắn có một cách thông minh siêu đơn giản để làm điều này, nhưng vì lịch sử trong zshell dường như được đặt bí danh cho fc, không có cách nào để sử dụng các thủ thuật được đề cập trong Cách xóa một dòng khỏi lịch sử? .

Bất kỳ con trỏ về làm thế nào để làm điều này? Trường hợp sử dụng của tôi sẽ là xóa lệnh đã ban hành cuối cùng khỏi lịch sử để nó dừng tự động hoàn thành (chủ yếu là khi bạn nhập sai thứ gì đó và nó tiếp tục hiển thị).

Tôi biết tôi có thể nhận được lệnh ban hành cuối cùng bằng cách làm

history | tail -n 1, nhưng history -d không hoạt động và tôi không thể tìm thấy tài liệu phù hợp cho zsh.

Câu trả lời:


8

Zsh không cung cấp một cơ sở phiên bản lịch sử thực sự. Lịch sử lệnh về cơ bản là chỉ đọc. Tất cả bạn có thể làm là thay thế nó bán buôn.

Để chỉnh sửa lịch sử dòng lệnh:

  1. Lưu nó vào một tập tin: fc -W
  2. Chỉnh sửa tập tin
  3. Tải lịch sử từ tệp: fc -R

Bạn có thể chọn tên tệp bằng cách cài đặt HISTFILE.

Mã chưa được kiểm tra:

remove_last_history_entry () {
  setopt local_options extended_history no_hist_save_no_dups err_return

  local HISTFILE=~/.zsh_history_tmp_$$ SAVEHIST=$HISTSIZE
  fc -W
  ed -s $HISTFILE <<EOF >/dev/null
d
w
q
EOF
  fc -R
}

6

Thông thường bạn chỉ có thể xóa dòng khỏi ~/.zsh_history, nhưng nếu bạn không thể tìm thấy nó hãy tìm ~/.zshrcvị trí của tệp lịch sử của bạn.

Sau đó sử dụng bất kỳ trình soạn thảo văn bản nào bạn chọn để xóa (các) dòng vi phạm. Ngoài ra, chỉ cần xóa toàn bộ tệp và đóng tất cả các phiên bản zsh và bắt đầu một tệp mới. Lịch sử thanh trừng!


2

Vì vậy, yeah, đây là một chủ đề cũ, nhưng không có câu hỏi nào trong số này trả lời cho tôi vì vậy tôi chỉ dành nhiều năm cố gắng để tìm ra điều này quá!

Đây là giải pháp của tôi với lời cảm ơn từ @Gilles về gợi ý sử dụng 'fc -R' và 'fc -W' :).

Dán đoạn script bên dưới này vào tệp .zshrc của bạn.

tải lại với nguồn .zshrc

sau đó nhập 'quên' để quên lệnh cuối cùng: D. gõ 'quên 3' để quên 3 lệnh cuối. Một số shizz gợi cảm.

Nhấn mũi tên lên sẽ đưa bạn đến lệnh cuối cùng và sẽ không nhớ từ 'quên' cả :).

Đã cập nhật: Đã thêm đường dẫn về nhà, vì vậy nó hoạt động trong tất cả các thư mục bây giờ lol.

Cập nhật 2: Đã thêm khả năng chuyển số lệnh cuối cùng bạn muốn quên: D. Hãy thử 'quên 2' để quên 2 lệnh cuối: D.

# Put a space at the start of a command to make sure it doesn't get added to the history.
setopt histignorespace

alias forget=' my_remove_last_history_entry' # Added a space in 'my_remove_last_history_entry' so that zsh forgets the 'forget' command :).

# ZSH's history is different from bash,
# so here's my fucntion to remove
# the last item from history.
my_remove_last_history_entry() {
    # This sub-function checks if the argument passed is a number.
    # Thanks to @yabt on stackoverflow for this :).
    is_int() ( return $(test "$@" -eq "$@" > /dev/null 2>&1); )

    # Set history file's location
    history_file="${HOME}/.zsh_history"
    history_temp_file="${history_file}.tmp"
    line_cout=$(wc -l $history_file)

    # Check if the user passed a number,
    # so we can delete x lines from history.
    lines_to_remove=1
    if [ $# -eq 0 ]; then
        # No arguments supplied, so set to one.
        lines_to_remove=1
    else
        # An argument passed. Check if it's a number.
        if $(is_int "${1}"); then
            lines_to_remove="$1"
        else
            echo "Unknown argument passed. Exiting..."
            return
        fi
    fi

    # Make the number negative, since head -n needs to be negative.
    lines_to_remove="-${lines_to_remove}"

    fc -W # write current shell's history to the history file.

    # Get the files contents minus the last entry(head -n -1 does that)
    #cat $history_file | head -n -1 &> $history_temp_file
    cat $history_file | head -n "${lines_to_remove}" &> $history_temp_file
    mv "$history_temp_file" "$history_file"

    fc -R # read history file.
}

Vì vậy, có một vài điều đang diễn ra ở đây. Lệnh này sẽ cho phép chúng ta nhập một khoảng trắng trước bất kỳ lệnh nào và nó sẽ không được thêm vào lịch sử.

setopt histignorespace

Vì vậy, chúng ta có thể nhấn phím cách và nhập 'echo hi', nhấn enter và khi chúng ta nhấn mũi tên lên, 'echo hi' không có trong lịch sử của chúng ta :).

Lưu ý cách bí danh 'quên' có khoảng trắng trước my_remove_last_history_entry. Điều này là để zsh không lưu 'quên' lịch sử của chúng tôi.

Hàm giải thích

ZSH sử dụng fc cho lịch sử hoặc một cái gì đó, vì vậy chúng tôi thực hiện 'fc -W' để viết các lệnh hiện tại của chúng tôi vào tệp lịch sử, chúng sử dụng 'head -n -1' để cắt lệnh cuối cùng khỏi tệp. Chúng tôi lưu kết quả đầu ra đó vào một tệp tạm thời và sau đó thay thế tệp lịch sử gốc bằng tệp tạm thời. Và cuối cùng tải lại lịch sử với fc -R.

Tuy nhiên, có một vấn đề với chức năng được cố định với bí danh.

Nếu chúng ta chạy hàm theo tên của nó, nó sẽ xóa lệnh cuối cùng, đó là lệnh gọi hàm. Đây là lý do tại sao chúng tôi sử dụng bí danh với một cuộc gọi đến nó bằng một khoảng trắng, do đó zsh không thêm tên hàm này vào tệp lịch sử, làm cho mục nhập cuối cùng là mục chúng tôi muốn: D.


Nếu lệnh cuối cùng là đa dòng thì sao?
avp

Điều này nên được bình chọn là câu trả lời chính thức. Cảm ơn.
gsl

1

Trong zsh, đặt histignorespacetùy chọn ( set -o histignorespace). Và trong bash, thêm ignorespacehoặc ignoreboth(một số bản phân phối đã làm điều đó trong mặc định ~/.bashrc) thành $HISTCONTROLhoặc đặt HISTIGNORE=' *', sau đó bạn có thể bắt đầu lệnh hiện tại bằng <dấu cách> để tránh ghi lại nó.

:
 : none
fc -nl -1

:

Trong zsh, bạn vẫn có thể nhớ lại lệnh trước đó một lần, nhưng nó không được lưu trong lịch sử.


Điều này không giải quyết câu hỏi.
Chris Trang
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.