Как я могу восстановить поврежденный файл истории ZSH из памяти?

Вы можете создать базу данных SQLite и выполнять SQL-выборки из нее, что, вероятно, было бы более чистым в реализации и подготовило бы вас к более переносимой работе в дальнейшем.

Но вот примерная идея. Допустим, у меня есть 2 файла:

$ more index.txt new_vals.txt 
::::::::::::::
index.txt
::::::::::::::
1_,2_,4_,5_
::::::::::::::
new_vals.txt
::::::::::::::
5_,2_,1_,4
2_,5_,1_,4

С помощью этой команды мы можем найти соответствие:

$ for i in $(<new_vals.txt); do nums=${i//_,/}; \
        grep -oE "[${nums}_,]+" index.txt; done
1_,2_,4_,5_
1_,2_,4_,5_

Это демонстрирует, что мы можем сопоставить каждую строку из new_vals.txt с существующей строкой в index.txt.

UPDATE #1

Основываясь на правке ОП, можно сделать то, что он хочет, используя модификацию вышеописанного подхода.

$ for i in $(<new_vals.txt); do 
  nums=${i//_,/} 

  printf "# to check: [%s]" $i
  k=$(grep -oE "[${nums}_,]+" index.txt | grep "[[:digit:]]_$")
  printf " ==> match: [%s]\n" $k

done

С модифицированной версией тестовых данных:

$ more index.txt new_vals.txt 
::::::::::::::
index.txt
::::::::::::::
1_,2_,4_,5_
0_,2_,3_,9_
::::::::::::::
new_vals.txt
::::::::::::::
5_,2_,1_,4_
2_,5_,1_,4_
1_,1_,1_,1_
1_,2_,4_,4_

Теперь, когда мы запускаем вышеописанное (для простоты помещенное в скрипт, parser.bash):

$ ./parser.bash 
# to check: [5_,2_,1_,4_] ==> match: [1_,2_,4_,5_]
# to check: [2_,5_,1_,4_] ==> match: [1_,2_,4_,5_]
# to check: [1_,1_,1_,1_] ==> match: []
# to check: [1_,2_,4_,4_] ==> match: []

Как это работает

Вышеописанный метод работает, используя некоторые ключевые характеристики, проявляющиеся в природе ваших данных. Например. Только совпадения будут заканчиваться цифрой, за которой следует знак подчеркивания. grep "[[:digit:]]_$" выбирает только эти результаты.

Другая часть скрипта, grep -oE "[${nums}_,]+" index.txt выберет строки, содержащие символы строк из файла new_vals.txt, которые соответствуют строкам из index.txt.

Дополнительные настройки

Если природа данных такова, что длина строк может быть разной, то 2-й grep нужно будет расширить, чтобы гарантировать, что мы выбираем только строки достаточной длины. Есть несколько способов добиться этого, либо расширив шаблон, либо используя счетчик, возможно, с помощью wc или других средств, которые подтвердят, что совпадения определенного типа.

Расширение шаблона следующим образом:

k=$(grep -oE "[${nums}_,]+" index.txt | \
    grep "[[:digit:]]_,[[:digit:]]_,[[:digit:]]_,[[:digit:]]_$")

Позволит избавиться от строк типа:

$ ./parser2.bash 
# to check: [5_,2_,1_,4_] ==> match: [1_,2_,4_,5_]
# to check: [2_,5_,1_,4_] ==> match: [1_,2_,4_,5_]
# to check: [1_,1_,1_,1_] ==> match: []
# to check: [1_,2_,4_,4_] ==> match: []
# to check: [1_,2_,5_] ==> match: []
1
28.12.2018, 03:42
1 ответ

Копаясь в man-странице ZSHBUILTINS(1), я обнаружил, что:

fc -W.zsh_history_from_ram

записывает в файл историю в том же формате, в котором она сохранена zshв ~/.zsh_history. Это будет работать до тех пор, пока у вас есть сеанс оболочки, история которого все еще хранится в памяти.

5
28.01.2020, 00:21

Теги

Похожие вопросы