Как удалить дубликаты в моем .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 будет фактически записана дважды. Я думал о периодическом запуске w / 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 для проверки и убедиться, что нет подключенных сеансов до запуска скрипта фильтрации?

  • Сортировка не использует естественный порядок
  • Как использовать grep, sort и uniq для создания трех полей вывода
  • суммы столбцов на основе совпадающих полей
  • «Подсчитайте, сколько разных начальных букв написано в именах языков»
  • Awk / bash Keep line containg только 3 поля
  • печатать родительские каталоги полный путь вывода вывода
  • Почему эта команда не сортируется на основе индекса uniq?
  • Где исчезла моя строка `uniq` или` sort -u`, с некоторыми символами юникода
  • 5 Solutions collect form web for “Как удалить дубликаты в моем .bash_history, сохраняя заказ?”

    Сортировка истории

    Эта команда работает как sort|uniq , но сохраняет линии на месте

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

    В принципе, добавляет к каждой строке свой номер. После sort|uniq -ing все строки сортируются в соответствии с их первоначальным порядком (используя поле номера строки), и поле номера строки удаляется из строк.

    Это решение имеет недостаток в том, что он не определен, который является представителем класса равных строк, который сделает его на выходе, и поэтому его положение в конечном выходе не определено. Однако, если выбран последний представитель, вы можете sort ввод вторым ключом:

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

    Управление .bash_history

    Для повторного чтения и записи истории вы можете использовать history -a и history -w соответственно.

    Таким образом, я искал то же самое, когда меня раздражали дубликаты, и обнаружил, что если я отредактирую свой файл ~ / .bash_profile (Mac) с помощью:

     export HISTCONTROL=ignoreboth:erasedups 

    Он делает именно то, что вы хотели, он только сохраняет последнюю из любой команды. ignoreboth на самом деле так же, как делать ignorespace:ignoredups и что вместе с erasedups выполняет свою работу.

    По крайней мере, на моем терминале Mac с bash эта работа идеальна. Найди его здесь на askubuntu.com .

    Нашли это решение в дикой природе и испытали:

     awk '!x[$0]++' 

    В первый раз отображается конкретное значение строки ($ 0), значение x [$ 0] равно нулю.
    Значение нуля инвертируется с помощью ! и становится единым.
    Оператор, который оценивает один, вызывает действие по умолчанию, которое является печатью.

    Поэтому в первый раз, когда отображается конкретный $0 , он печатается.

    В следующий раз (повторы) значение x[$0] было введено,
    его отрицаемое значение равно нулю, а утверждение, которое оценивается в ноль, не печатается.

    Чтобы сохранить последнее повторяющееся значение, отмените историю и используйте один и тот же awk:

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

    Они будут содержать последние дублированные строки:

     ruby -i -e 'puts readlines.reverse.uniq.reverse' ~/.bash_history tac ~/.bash_history | awk '!a[$0]++' | tac > t; mv t ~/.bash_history 

    Расширение ответа Клейтона:

     tac $HISTFILE | awk '!x[$0]++' | tac | sponge $HISTFILE 

    tac переверните файл, убедитесь, что вы установили moreutils чтобы у вас была sponge , иначе используйте временный файл.

    Linux и Unix - лучшая ОС в мире.