bash 쉘 기록에서 특정 문자열을 포함하는 모든 항목을 삭제하는 명령이나 방법이 있습니까? 이는 기록에서 비밀번호가 포함된 명령을 삭제하는 데 유용합니다. 각 기록 항목을 번호별로 삭제할 수 있다는 것을 알고 있지만 문제는 한 번에 하나의 항목만 삭제하고 새 항목을 삭제하려면 매번 번호를 삭제해야 한다는 것입니다.
예를 들어. History 명령에 비밀번호 abcabc가 포함된 5개의 항목이 표시됩니다. 문자열 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
ignorespace
bash
promtpt:$ sed -i '/abcabc/d' /home/user/.bash_history
$
와 명령 사이의 공백에 유의하세요. 이로 인해 bash 기록에서 해당 줄이 무시됩니다.
-i
: 파일을 인라인으로 편집하는 것을 의미합니다.
d
마지막은 사이에 표현식이 포함된 줄을 제거하는 것을 의미합니다 /
.
이 솔루션은 Linux에서만 작동합니다 GNU sed
.