Eu tenho um cenário em que preciso desarticular os dados para alcançar o relacionamento pai-filho. Meus dados de origem são os seguintes:
Key_Col|Hierarquia
1|a,b,c,d
2|a,b,c,d,e
Minha saída esperada abaixo:
Chave Col | Criança | Pai |
---|---|---|
1 | d | c |
1 | c | b |
1 | b | a |
1 | a | nulo |
2 | e | d |
2 | d | c |
2 | c | b |
2 | b | a |
2 | a | nulo |
Você poderia me informar como posso conseguir isso por meio de um script bash?
O script que usei é:
Var="1|a,b,c,d";
for i in $Var
do
Key=`echo $i |cut -d'|' -f1`
Hierarchy=`echo $i |cut -d'|' -f2`
Delim_Count=`echo ${Hierarchy} |awk -F',' '{ print NF-1 }'`
for (( c=$Delim_Count+1; c>=1; c-- ))
do
Parent=`echo ${Hierarchy} |cut -d',' -f$c`
Prev=`expr $c - 1`
if [ $Prev -ne 0 ]; then
Child=`echo ${Hierarchy} |cut -d',' -f${Prev}`
echo "${Key}|${Parent}|${Child}"
else
echo "${Key}|${Parent}|"
fi
done
done
Mas o problema é que, se houver mais de 100 linhas, o script levará muito tempo para ser concluído.
Coisas como essas geralmente são mais fáceis de fazer com uma linguagem feita para processar texto ou dados estruturados. Abaixo está uma solução usando o utilitário de processamento de texto padrão
awk
e outra usando Miller (mlr
), uma ferramenta usada especificamente para processar dados estruturados (seus dados se parecem com CSV).Com
awk
:O
awk
código acima lê cada linha de entrada como um conjunto de|
campos delimitados por -. Ele divide o segundo campo nas vírgulas na matriza
. O elemento zero do array é definido como a stringnull
(split()
cria um array cujo primeiro índice é 1 , então sabemos que podemos usar o índice 0 sem sobrescrever os dados). Em seguida, iteramos do final da matriz para o início, gerando o valor do primeiro campo com o elemento atual da matriz e o elemento anterior na matriz. Quando chegarmos à última iteração, nossa variável de loop terá o valor 1, o que faz com quea[1]
ea[0]
(null
) sejam impressos.A primeira linha de entrada, que contém um cabeçalho, é tratada de forma diferente. Em vez de dividir etc., o código imprime três campos: o primeiro campo da entrada e um campo cada para as strings
Child
eParent
. O bloco condicionalNR==1
faz isso.O
awk
código, reformatado para facilitar a leitura:Como a entrada se parece com CSV, pode ser mais seguro usar uma ferramenta compatível com CSV para processá-la. Miller (
mlr
) é uma dessas ferramentas:A
put
expressão Miller segue o mesmo esquema doawk
código acima, mas sem ter que lidar com os cabeçalhos como um caso especial já que Miller sabe como ler e usar estes:Miller nos permite produzir o resultado de muitas formas diferentes ajustando as opções antes do
put
subcomando.Saída "barrada" bem impressa:
JSON:
(etc.)