題 從Bash歷史文件中刪除某一行


如何從中刪除某一行 history的數據庫?


130
2018-01-31 15:43


起源




答案:


您需要註銷並重新登錄或運行 history -a 所以當前的歷史記錄致力於磁盤。

然後只需編輯該文件 ~/.bash_history


97
2018-01-31 16:01



如果設置了HISTFILE環境變量,則歷史文件不是〜/ .bash_history而是$ {HISTFILE}。 - Karolos
退出shell時,條目將寫入歷史記錄文件中。因此,在輸入您要刪除的命令後,您需要註銷並重新登錄,或使用“history -d xxxx”將其從當前shell會話中刪除。 - harmic
但是如何刪除編輯歷史文件的記錄? - chiliNUT
@chiliNUT:剛開始你的命令(例如 vim ~/.bash_history)有空間;以空格開頭的命令通常不會被記錄(參見 $HISTCONTROL)。 - cYrus
我認為在我的發行版中不是這種情況,但總的來說這是有道理的 - chiliNUT


您可以通過兩個步驟使用命令行從歷史文件中刪除:

  1. 打字 history -d <line_number> 從內存中的歷史記錄中刪除指定的行。
  2. 打字 history -w 將當前的內存中歷史記錄寫入 ~/.bash_history 文件。

這兩個步驟一起從內存中永久刪除該行 歷史 從... .bash_history的 文件也是。


141
2018-01-31 16:09



如何刪除最後一個 history -w 從歷史? - KrIsHnA
@KrIsHnA手動編輯〜/ .bash_history - Alexander Myshov
或者在它之前添加一個空格以防止它被添加,就像在@tao的答案中一樣 - Mark
找到 <line_number> 只是 history | grep [unwanted_content] 獲取包含所有行的列表 [unwanted_content] (比如密碼)。 - AvL
如何刪除多個(特定)行(按ID)? - Pathros


防止 首先將命令添加到歷史記錄中,確保環境變量 HISTCONTROL 在其冒號分隔值中包含值 ignorespace例如,(例如添加到 .bashrc):

$ export HISTCONTROL=ignorespace

這將阻止任何帶有前導空格的命令被添加到歷史記錄中。然後,您可以通過運行完全清除歷史記錄

$  history -c -w
  ^-- additional space character

37
2018-02-01 22:19





首先,如果您要發布的命令是敏感的,不安全的,或者您只是不需要它使您的歷史變得混亂,那麼最好/最快的是阻止它首先進入歷史記錄。確保這一點 $HISTCONTROL 包含 ignorespace

(bash)$ echo $HISTCONTROL
ignoredups:ignorespace

然後使用空格繼續執行歷史記錄中不需要的任何命令:

(bash)$  sensitive-cmd-with --password 82cf7dfe
(bash)$  rm -r... # One-off recursive remove; mustn't be accidentally repeated!

如果您不小心將不需要的命令放入歷史記錄中,假設您的bash會話仍處於打開狀態,則該命令尚未觸及該磁盤。要刪除歷史記錄中的上一個命令,請發出:

(bash)$  history -d $((HISTCMD-1))

注意領先的空間;這個命令需要 ignorespace,否則它只會刪除自己!

如果要刪除最後幾個命令,請查找最後一個和第一個歷史記錄編號:

(bash)$  history 5
  598  ok
  599  sensitive
  600  unsafe
  601  doesn\'t-work
  602  otherwise-unwanted

在這種情況下602和599.然後發出:

(bash)$  for i in {602..599}; do history -d $i; done

(無 ignorespace,它將是603..599。)

如果你不想要 任何 從當前會話到磁盤的歷史記錄,退出使用:

(bash)$ kill -9 $$

到目前為止,這種方法甚至不會將敏感的歷史項目寫入磁盤以獲得額外的安全性,因為理論上從非易失性介質中刪除的數據仍然可以恢復。

但是,如果您要刪除的命令來自之前的會話,則它們將被附加到 $HISTFILE 在退出。使用上述命令操作歷史記錄仍然只會 附加 剩餘的  項目到 $HISTFILE在退出。至 覆蓋 該 $HISTFILE 與當前會議的觀點 整個 歷史, 馬上, 問題:

(bash)$  history -w

當然,對於已經在磁盤上的歷史項目,可以選擇編輯歷史記錄 history -d 命令然後發出 history -w,就是編輯了 $HISTFILE 用文本編輯器。


30
2018-06-18 16:33



“用上述命令操縱歷史記錄仍然只會 附加 剩餘的 新 項目到 $HISTFILE, 在退出“實際上,這並不完全正確。它似乎只附加了從原始歷史長度“伸出”的剩餘新項目。例如。如果我刪除5個原始項目並添加15個新項目,則僅附加最後10個新項目,而我希望附加所有15個新項目。我認為這是一個錯誤,因為我無法看到這是多麼令人滿意的功能。 - James Haigh
我猜bash注意到原始長度。在會話結束時,它可能會附加數量大於此值的項目。如果每次刪除其數量小於或等於此值的項目時該值都會減少,則它將按預期工作。 ;-) - James Haigh


幾種技巧:

防止敏感信息存儲在歷史文件中

如果您在命令行上輸入了一些密碼,然後意識到所有命令都已記錄,您可以:

  1. 強制退出當前會話而不保存歷史記錄:

     kill -9 $$
    

    這將刪除所有當前歷史記錄。

  2. 類型 ↑(向上箭頭) 在打開的bash會話中,直到顯示敏感信息,然後使用行編輯鍵擊 按Ctrl+w ^ 刪除敏感信息,和 然後  ↓(向下箭頭) 直到提示新的空行, 之前 打字 輸入

從歷史文件中刪除敏感信息

如果您發現已存儲敏感信息,並且您想刪除它,而不是整個歷史記錄:

一個簡單的 sed 命令可以完成這項工作:

sed -e '/SeNsItIvE InFo/d' -i .bash_history

但是,當您鍵入此內容時,您將創建另一個包含您要刪除的搜索模式(敏感信息)的歷史記錄行。所以你可以:

sed -e "/$(head -n1)/d" -i .bash_history

這將運行 head -n1 來自終端的輸入。 您的終端似乎已掛起(沒有提示); 只需鍵入要從文件中刪除的信息即可。 這是讓你輸入(部分)命令的技巧 沒有實際輸入命令行, 因此沒有資格列入歷史記錄。 然後 sed 將使用您鍵入的文本進行搜索 .bash_history 並刪除包含敏感信息的所有行。 注意:如果您的敏感信息模式包含斜杠, 你必須用反斜杠逃脫它們, 或者改變 sed 命令使用此語法 指定未出現在模式中的分隔符:

sed -e "\|$(head -n1)|d" -i .bash_history

另一種方法可能是僅刪除敏感信息,但保留包含信息的命令。為此,您可以使用您選擇的替換文本替換敏感信息:

sed -e "s/$(head -n1)/Santa Claus/g" -i .bash_history.

從特定樹中的任何文件中刪除敏感信息

最後,確保這不會留下來 另一個 遺忘的文件:

SENSITIVEINFO="$(head -n1)"
find . -type f -print0 | xargs -0 grep -l "$SENSITIVEINFO"

將列出所有相關文件。

find . -type f -print0 |
    xargs -0 grep -l "$SENSITIVEINFO" |
    tr \\n \\0 |
    xargs -0 sed -e "s/$SENSITIVEINFO/Santa Claus/g" -i

將替換所有文件中出現的所有敏感信息 在根目錄的目錄樹中 .。 注意:即使此命令使用 xargs -0, 它不會處理名稱中帶有換行符的文件。


14
2017-07-19 12:50





按下可找到要刪除的行 ↑(向上箭頭) 直到它出現,然後按 按Ctrl+ü。這應該刪除該行。

如果你使用 history 命令,你可以看到該行已被星號代替。


10
2018-04-01 16:00



實際上,我相信你必須向上光標,按Ctrl + U, 然後向上或向下光標到另一行 (可能是列表底部的空白)。另外,嚴格來說,該行沒有用星號代替。相反,命令已被刪除,並且 歷史編號 附上了一個 *。 - G-Man
使用Ctrl + R(反向增量歷史搜索),這變得更加強大, [結束],Ctrl + U. - sehe


如果你需要同時刪除幾行我通常使用這個:

history | grep <string> | cut -d ' ' -f 3 | awk '{print "history -d " $1}'

如果您需要刪除最後一個命令,您可以使用:

history -d $((HISTCMD-2))

4
2018-01-07 05:53



這看起來很有效但是 history | grep <string> 仍然顯示它聲稱要刪除的所有行... - Brock Hensley
這將在刪除fisrt後刪除錯誤的歷史記錄行!! - mivk
但幸運的是,它只打印錯誤的刪除命令。以下將打印正確的刪除命令: history | grep XYZ | grep -v grep | tac | awk '{print "history -d", $1}' - mivk


如果您需要從歷史記錄中刪除一系列行,則以下bash函數可以為您節省一些時間:

function histdel() {
    [ $# -eq 1 ] && history -d "$1" && history -w
    if [ $# -eq 2 -a "$1" -le "$2" ]; then
        for n in `seq "$2" "$1"`; do
            history -d "$n"
        done
        history -w
    fi
}

通常應添加功能 $HOME/.bashrc。要使用imediatelly函數,您需要讓正在運行的shell再次讀取該文件(. $HOME/.bashrc)。然後刪除例如命令200-210來自歷史:

$ histdel 200 210

(注意:如果您搜索從bash歷史記錄中刪除一系列命令,則此問題屬於頂級搜索結果。因此,雖然上述問題超出了問題所要求的範圍,但對某些讀者可能會有用。)


3
2017-10-26 14:09



替代形式 for 聲明: for n in $(seq "$2" "$1") 在某種程度上是風格偏好,如果 seq 不行,試試 for ((n="$2"; n>="$1"; n--))。 - Scott


history | sed -i 59d

59是行號。不能比這更甜美:)


3
2018-04-03 21:16





試試這些,

$ history

這將顯示歷史和命令的id,例如


  。
  211 ls
  212 javac Welcome.java
  213 java歡迎
  。
  。

使用,

$ history -d 211

這裡211是歷史的id。現在檢查一下

$ history


  。
  211 javac Welcome.java
  212 java歡迎
  。
  。


3
2018-03-04 11:16





我知道已經有很長一段時間了,因為這個問題已經被問到並回答了,但我會告訴你我清理歷史文件並同時註銷的方法。

我跑: history -w && nano "${HISTFILE}" && history -c && exit

它的作用很簡單:

  1. history -w :在內部寫入緩存的歷史記錄 "${HISTFILE}"
  2. nano "${HISTFILE}" :允許我編輯 "${HISTFILE}" 您可以使用sed腳本或任何想要清理的腳本 "${HISTFILE}"
  3. history -c :清除緩存的歷史記錄,以便不附加此最後一個命令。
  4. exit :登錄我添加緩存的歷史...但它是空的;)

在該命令之後,您將使用乾淨的歷史記錄文件註銷。 登錄查看您的歷史記錄;)

我希望這會對​​某人有所幫助。


2
2017-09-30 04:57