
有沒有任何命令或方法可以從 bash shell 的歷史記錄中刪除包含特定字串的所有條目?這對於刪除歷史記錄中包含密碼的命令很有用。我知道我們可以透過編號刪除每個歷史記錄條目,但問題是它一次只能刪除一個條目,而我每次都需要取出編號來刪除新條目。
例如。歷史命令顯示 5 個包含密碼 abcabc 的條目,我想從包含字串 abcabc 的歷史命令中刪除所有條目
975 2019-03-15 11:20:30 ll
976 2019-03-15 11:20:33 ll cd
977 2019-03-15 11:20:36 ll CD
978 2019-03-15 11:20:45 chown test1:test1 CD
979 2019-03-15 11:20:53 chown test1:test1 ./CD
980 2019-03-15 11:20:57 chown test1:test1 .\CD
981 2019-03-15 11:22:04 cd /tmp/logs/
982 2019-06-07 10:36:33 su test1
983 2019-08-22 08:35:10 su user1
984 2019-08-22 08:35:15 /opt/abc/legacy.exe -password abcabc
985 2019-09-24 07:20:45 cd /opt/test1/v6r2017x
986 2019-09-24 07:20:46 ll
987 2019-09-24 07:21:18 cd /tmp/
988 2019-09-24 07:21:19 ll
989 2019-09-24 07:21:24 cd linux_a64/
990 2019-09-24 07:21:25 /opt/abc/legacy.exe -password abcabc
991 2019-09-24 07:24:03 cd build/
992 2019-09-24 07:24:04 ll
993 2019-09-24 07:24:07 cd ..
994 2019-09-24 07:24:10 /opt/abc/legacy.exe -password abcabc
995 2019-09-24 07:24:15 cd someapp/bin
996 2019-09-24 07:24:21 ll
997 2019-09-24 07:24:33 cd .
998 2019-09-24 07:24:35 cd ..
999 2019-09-24 07:24:36 ll
嘗試了以下命令,但出現錯誤,如下所示
servername:~ # sed -i 'g/abcabc/d' /home/user1/.bash_history
sed: -e expression #1, char 2: extra characters after command
預期:沒有錯誤,並且所有包含字串 abcabc 的條目都應被刪除。
答案1
另一個類似於@cprn的答案,但使用awk
(而不是cut
)和一個函數:
function del_word_history () {
if [ -z "${1}" ]; then return false; fi
mapfile -t result <<< "$(history | grep "${1}" | tac | awk '{print $1}')"
for idx in "${result[@]}"; do
history -d $idx
done
}
tac
反轉輸出的行(一些帖子指出這並不適用於所有系統)[-z $1 ]
:true
如果傳遞給函數 ($1
) 的第一個參數為空。mapfile -t
(手冊頁;一些指南): 讀stdin
入數組變數 (result
)"${result[@]}"
返回數組
awk '{print $1}'
(GNU 使用者指南,簡要指南,手冊頁):用於兩者:識別匹配並處理它。它將由空格(預設)分隔的資料分割並將其儲存在$n
變數中。'{pring $1}'
讀取為print
對第一個單字執行操作。
用法:
del_word_history history
del_word_history abcabc
history -w
下面是一個更乾淨的解決方案檢查我們是否獲得了idx
的編號history
,而不是多行條目的其他單字:
function del_word_history () {
if [ -z "${1}" ]; then return false; fi
mapfile -t lines <<< "$(history | grep "${1}" | tac)"
for line in "${lines[@]}"; do
idx="$(printf '%s' "${line}" | awk '{ if ($1 ~ /^[0-9]+$/) { print $1 } }')"
if [ -n "${idx}" ]; then
echo "removing line ${idx}"
history -d $idx
fi
done
}
主要區別是:
lines
我們透過以下方式取得數組變數中的完整行mapfile
awk '{ if ($1 ~ /^[0-9]+$/) { print $1 }}'
檢查每行的第一個單字是否是一個數字,並且它stdout
是相同的第一個單字(並獲取變數idx
)[ -n ${idx}" ] just checks if
idx` 不為空
答案2
我知道它很舊,但我只是像這樣循環執行:
for ln in $( history | grep my_phrase | cut -f2 -d' '); do
history -d $ln
done
$(...)
- 命令替換,stdout
返回...
cut -f2 -d' '
- 剪下第二列空格分隔的輸出,即行號history -d $ln
- 從歷史記錄中刪除給定的行號
一張襯墊,方便複製貼上:
for ln in $( history | grep my_phrase | cut -f2 -d' '); do history -d $ln; done
答案3
您可以使用sed
從 中刪除條目.bash_history
。
但由於它是一個密碼,以避免在 CLI 中再次輸入密碼,我建議您編輯文件.bashrc
並確保將行HISTCONTROL
設為ignoreboth
or ignorespace
。這將允許您輸入命令,bash
並且如果它們以空格開頭,則不會將它們放入歷史記錄中:
promtpt:$ sed -i '/abcabc/d' /home/user/.bash_history
$
請注意和 命令之間的空格,這將使該行在 bash 歷史記錄中被忽略。
-i
: 表示內聯編輯檔。
d
最後意味著刪除包含之間表達式的行/
。
此解決方案僅適用於 Linux GNU sed
。