วิธีการลบคำสั่งสุดท้าย (หรือคำสั่งปัจจุบันสำหรับโบนัส) จากประวัติ zsh


14

แน่นอนว่ามีวิธีที่ชาญฉลาดอย่างง่ายที่สุดในการทำเช่นนี้ แต่เนื่องจากประวัติใน zshell ดูเหมือนจะใช้นามแฝงเป็น fc จึงไม่มีวิธีใช้เทคนิคที่กล่าวถึงในวิธีการลบบรรทัดเดียวออกจากประวัติ .

ตัวชี้ใด ๆ เกี่ยวกับวิธีการทำเช่นนี้? กรณีการใช้งานของฉันคือการลบคำสั่งที่ออกล่าสุดจากประวัติดังนั้นจึงหยุดการเติมข้อความอัตโนมัติ (ส่วนใหญ่เมื่อคุณพิมพ์ผิดบางอย่าง

ฉันรู้ว่าฉันสามารถรับคำสั่งที่ออกล่าสุดโดยทำ

history | tail -n 1แต่ history -d ไม่ทำงานและฉันไม่พบเอกสารที่เหมาะสมสำหรับ zsh

คำตอบ:


9

Zsh ไม่มีสิ่งอำนวยความสะดวกรุ่นประวัติจริง ประวัติคำสั่งนั้นเป็นแบบอ่านอย่างเดียว สิ่งที่คุณสามารถทำได้คือแทนที่มันขายส่ง

หากต้องการแก้ไขประวัติบรรทัดคำสั่ง:

  1. บันทึกลงในไฟล์: fc -W
  2. แก้ไขไฟล์
  3. โหลดประวัติจากไฟล์: fc -R

HISTFILEคุณสามารถเลือกชื่อไฟล์โดยการตั้งค่า

รหัสไม่ได้ทดสอบ:

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

โดยปกติแล้วคุณสามารถลบบรรทัดออก~/.zsh_historyได้ แต่หากคุณไม่พบบรรทัดนั้นให้ค้นหา~/.zshrcตำแหน่งของไฟล์ประวัติของคุณ

จากนั้นใช้เครื่องมือแก้ไขข้อความที่คุณเลือกเพื่อลบบรรทัดที่ละเมิดออก หรือเพียงแค่ลบไฟล์ทั้งหมดและปิดอินสแตนซ์ zsh ทั้งหมดแล้วเริ่มใหม่ ล้างประวัติ!


2

ใช่แล้วนี่เป็นหัวข้อเก่า แต่คำถามเหล่านี้ไม่มีคำตอบสำหรับฉันดังนั้นฉันจึงใช้เวลานานพอที่จะคิดออกเช่นกัน!

นี่คือทางออกของฉันด้วยคำขอบคุณจาก @Gillesสำหรับคำใบ้ในการใช้ 'fc -R' และ 'fc -W' :)

วางสคริปต์ด้านล่างนี้ลงในไฟล์. zshrc ของคุณ

โหลดซ้ำกับซอร์ส. zshrc

จากนั้นพิมพ์ 'ลืม' เพื่อลืมคำสั่งสุดท้าย: D พิมพ์ 'forget 3' เพื่อลืม 3 คำสั่งล่าสุด Shizz เซ็กซี่บางอย่าง

การกดลูกศรขึ้นจะนำคุณไปยังคำสั่งสุดท้ายและจะไม่จดจำคำว่า 'ลืม' อย่างใดอย่างหนึ่ง :)

อัปเดต:เพิ่มเส้นทางบ้านดังนั้นจึงทำงานในไดเรกทอรีทั้งหมดได้แล้วตอนนี้ lol

อัปเดต 2:เพิ่มความสามารถในการส่งผ่านจำนวนคำสั่งสุดท้ายที่คุณต้องการลืม: D ลอง 'ลืม 2' เพื่อลืมคำสั่ง 2 คำสุดท้าย: 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.
}

มีบางสิ่งเกิดขึ้นที่นี่ คำสั่งนี้จะให้เราพิมพ์ช่องว่างก่อนคำสั่งใด ๆ และมันจะไม่ถูกเพิ่มลงในประวัติ

setopt histignorespace

ดังนั้นเราสามารถกด space bar และพิมพ์ 'echo hi' กด enter และเมื่อเรากดลูกศรขึ้น 'echo hi' ไม่ได้อยู่ในประวัติศาสตร์ของเรา :)

สังเกตว่านามแฝง 'ลืม' มีช่องว่างตรงหน้า my_remove_last_history_entry นี่คือเพื่อ zsh ไม่ได้บันทึก 'ลืม' ของเราในประวัติศาสตร์

ฟังก์ชั่นอธิบาย

ZSH ใช้ fc สำหรับประวัติหรือบางอย่างดังนั้นเราจึงทำ 'fc -W' เพื่อเขียนคำสั่งปัจจุบันของเราไปยังไฟล์ประวัติพวกเขาใช้ 'head -n -1' เพื่อตัดคำสั่งสุดท้ายออกจากไฟล์ เราบันทึกผลลัพธ์นั้นไปที่ไฟล์ชั่วคราวแล้วแทนที่ไฟล์ประวัติเดิมด้วย temp หนึ่ง และในที่สุดก็โหลดประวัติด้วย fc -R

อย่างไรก็ตามมีปัญหากับฟังก์ชั่นที่แก้ไขด้วยนามแฝง

หากเราเรียกใช้ฟังก์ชั่นตามชื่อมันจะลบคำสั่งสุดท้ายซึ่งเป็นการเรียกใช้ฟังก์ชัน นี่คือเหตุผลที่เราใช้นามแฝงที่มีการเรียกโดยใช้ช่องว่างเพื่อให้ zsh ไม่ได้เพิ่มชื่อฟังก์ชั่นนี้ลงในไฟล์ประวัติทำให้รายการสุดท้ายที่เราต้องการ: D


เกิดอะไรขึ้นถ้าคำสั่งสุดท้ายคือหลายบรรทัด?
AVP

ควรได้รับการโหวตให้เป็นคำตอบอย่างเป็นทางการ ขอบคุณ
gsl

1

ในzshตั้งค่าhistignorespaceตัวเลือก ( set -o histignorespace) และในbashเพิ่มignorespaceหรือignoreboth(การกระจายบางส่วนได้ทำในค่าเริ่มต้น~/.bashrc) ไปที่$HISTCONTROLหรือตั้งค่าHISTIGNORE=' *'แล้วคุณสามารถเริ่มต้นคำสั่งปัจจุบันด้วย<space>เพื่อหลีกเลี่ยงการบันทึก

:
 : none
fc -nl -1

:

ในzshคุณยังสามารถจำคำสั่งก่อนหน้านั้นได้ครั้งเดียว แต่จะไม่ถูกเก็บไว้ในประวัติ


สิ่งนี้ไม่ได้ตอบคำถาม
Chris หน้า
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.