Вы можете создать базу данных 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
.
Основываясь на правке ОП, можно сделать то, что он хочет, используя модификацию вышеописанного подхода.
$ 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: []
Копаясь в man-странице ZSHBUILTINS(1)
, я обнаружил, что:
fc -W.zsh_history_from_ram
записывает в файл историю в том же формате, в котором она сохранена zsh
в ~/.zsh_history
. Это будет работать до тех пор, пока у вас есть сеанс оболочки, история которого все еще хранится в памяти.