Você poderia configurar um banco de dados SQLite e realizar seleções de SQL a partir dele, o que provavelmente seria mais limpo de implementar e o configuraria para ser mais portátil posteriormente.
Mas aqui está uma idéia aproximada. Digamos que eu tenha 2 arquivos:
$ more index.txt new_vals.txt
::::::::::::::
index.txt
::::::::::::::
1_,2_,4_,5_
::::::::::::::
new_vals.txt
::::::::::::::
5_,2_,1_,4
2_,5_,1_,4
Com este comando, podemos corresponder:
$ for i in $(<new_vals.txt); do nums=${i//_,/}; \
grep -oE "[${nums}_,]+" index.txt; done
1_,2_,4_,5_
1_,2_,4_,5_
Isso demonstra que podemos corresponder cada linha de new_vals.txt
a uma linha existente em index.txt
.
UPDATE # 1
Com base na edição do OP, o seguinte faria o que ele quiser usando uma modificação da abordagem acima.
$ 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
Com uma versão modificada dos dados de teste:
$ 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_
Agora, quando executarmos o acima (coloque dentro de um script para simplificar, 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: []
Como funciona
O método acima funciona explorando algumas características-chave exibidas pela natureza dos seus dados. Por exemplo. Somente as correspondências terminarão com um dígito seguido por um sublinhado. O grep "[[:digit:]]_$"
seleciona apenas esses resultados.
A outra parte do script, grep -oE "[${nums}_,]+" index.txt
, selecionará as linhas que contêm caracteres das strings no arquivo new_vals.txt
, que correspondem às strings de index.txt
.
Ajustes adicionais
Se a natureza dos dados for tal que as strings podem ser variáveis em comprimento, então o segundo grep precisará ser expandido para garantir que estamos escolhendo apenas strings de tamanho suficiente. Existem várias maneiras de fazer isso, seja expandindo o padrão ou fazendo uso de um contador, talvez usando wc
ou algum outro meio, que confirmaria que as correspondências são de um certo tipo.
Expandindo assim:
k=$(grep -oE "[${nums}_,]+" index.txt | \
grep "[[:digit:]]_,[[:digit:]]_,[[:digit:]]_,[[:digit:]]_$")
Permitiria a eliminação de sequências como esta:
$ ./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: []