.bash_history에서 중복을 제거하고 순서를 유지하는 방법은 무엇입니까?

.bash_history에서 중복을 제거하고 순서를 유지하는 방법은 무엇입니까?

control+r나는 명령 기록을 검색하기 위해 재귀를 사용하는 것을 정말 좋아합니다 . 제가 사용하고 싶은 몇 가지 좋은 옵션을 찾았습니다.

# ignore duplicate commands, ignore commands starting with a space
export HISTCONTROL=erasedups:ignorespace

# keep the last 5000 entries
export HISTSIZE=5000

# append to the history instead of overwriting (good for multiple connections)
shopt -s histappend

나에게 유일한 문제는 erasedups연속된 중복 항목만 제거하는 것이었습니다. 따라서 다음 명령 문자열을 사용하십시오.

ls
cd ~
ls

명령 은 ls실제로 두 번 기록됩니다. 주기적으로 cron을 실행하는 것을 고려했습니다.

cat .bash_history | sort | uniq > temp.txt
mv temp.txt .bash_history

이렇게 하면 중복 항목이 제거되지만 안타깝게도 순서는 유지되지 않습니다. 해당 파일을 먼저 사용 하지 않으면 작동 sort하지 않을 것이라고 생각합니다 uniq.

.bash_history에서 중복을 제거하고 순서를 유지하는 방법은 무엇입니까?

추가 크레딧:

.bash_history스크립트를 통해 파일을 덮어쓰는 데 문제가 있나요? 예를 들어, Apache 로그 파일을 삭제하는 경우 nohup/Reset 신호를 보내 kill파일에 대한 연결을 플러시해야 한다고 생각합니다. 파일의 경우인 경우 필터 스크립트를 실행하기 전에 연결된 세션이 없는지 확인하고 확인하는 .bash_history데 사용할 수 있는 방법이 있을까요 ?ps

답변1

그래서 중복된 항목에 짜증이 난 후, 나는 똑같은 것을 찾고 있었고 다음을 사용하여 my ~/.bash_profile또는 my를 편집하면 다음을 발견했습니다 ~/.bashrc.

export HISTCONTROL=ignoreboth:erasedups

이는 사용자가 원하는 것을 거의 정확하게 수행하며 하나의 셸 인스턴스에 있는 최신 명령만 유지합니다. ignoreboth실제로 일을하고 ignorespace:ignoredupserasedups을 끝내십시오.

적어도 내 Mac 터미널에서는 bash가 완벽하게 작동합니다. 그것을 발견askubuntu.com을 방문하세요..

이는 ignoredups기존 에서는 도움이 되지 않습니다 .bash_history. 중복 항목은 사용될 때 파일에 계속 나타납니다 shopt -s histappend.

답변2

정렬 기록

이 명령은 다음과 유사하게 작동 sort|uniq하지만 줄을 제자리에 유지합니다.

nl|sort -k 2|uniq -f 1|sort -n|cut -f 2

기본적으로 각 줄 앞에 번호를 붙입니다. -ing 후에 sort|uniq모든 행은 원래 순서(행 번호 필드 사용)에 따라 다시 정렬되고 행 번호 필드는 행에서 제거됩니다.

이 솔루션의 결점은 동일한 선 클래스의 어떤 대표가 출력에 나타날지 정의되지 않았으므로 최종 출력에서 ​​해당 위치가 정의되지 않는다는 것입니다. 그러나 최신 대표자를 선택해야 하는 경우 sort두 번째 키를 통해 입력할 수 있습니다.

nl|sort -k2 -k 1,1nr|uniq -f1|sort -n|cut -f2

admin.bash_history

기록을 다시 읽고 다시 쓰려면 history -a각각 및를 사용할 수 있습니다.history -w

답변3

실제 환경에서 이 솔루션을 찾아 테스트했습니다.

awk '!x[$0]++'

행에서 특정 값($0)을 처음 볼 때 x[$0]의 값은 0입니다.
0 값이 반전 !되어 1이 됩니다.
1로 평가되는 명령문은 인쇄라는 기본 동작을 발생시킵니다.

그래서 특정한 것이 처음으로 $0보이면 인쇄됩니다.

다음(반복되는) 값이 x[$0]증가할 때마다
음수 값은 0이 되고 0으로 평가되는 명령문은 인쇄되지 않습니다.

마지막 중복 값을 유지하려면 기록을 되돌리고 동일한 awk를 사용하십시오.

awk '!x[$0]++' ~/.bash_history                 # keep the first value repeated.

tac ~/.bash_history | awk '!x[$0]++' | tac     # keep the last.

답변4

오래된 글이지만 중복 없이 여러 터미널을 열고 창 간 기록을 동기화하려는 사용자에게는 영구적인 문제입니다.

.bashrc의 내 솔루션:

shopt -s histappend
export HISTCONTROL=ignoreboth:erasedups
export PROMPT_COMMAND="history -n; history -w; history -c; history -r"
tac "$HISTFILE" | awk '!x[$0]++' > /tmp/tmpfile  &&
                tac /tmp/tmpfile > "$HISTFILE"
rm /tmp/tmpfile
  • histappend 옵션은 버퍼의 히스토리를 히스토리 파일($HISTFILE)의 끝에 추가합니다.
  • ignoreboth 및 Erasedups는 중복 항목이 $HISTFILE에 저장되는 것을 방지합니다.
  • 기록 캐시를 업데이트하라는 프롬프트 명령
    • history -n$HISTFILE에서 마지막 캐리지 리턴 이후 다른 터미널에 나타날 수 있는 모든 행을 읽습니다.
    • history -w업데이트된 버퍼를 $HISTFILE에 쓰기
    • history -c중복이 발생하지 않도록 버퍼를 지우십시오.
    • history -r$HISTFILE을 다시 읽고 이제 비어 있는 버퍼에 추가
  • awk 스크립트는 마주치는 각 행의 첫 번째 발생을 저장합니다. tac되돌린 다음 역사상 가장 최근 명령으로 저장할 수 있도록 다시 되돌립니다.
  • rm /tmp 파일

새 셸을 열 때마다 기록이 지워지고, Enter다른 셸/터미널 창에서 키를 누를 때마다 파일에서 이 기록이 업데이트됩니다.

관련 정보