Eu tenho 2 arquivos contendo list. A coluna 1 é userIds e a coluna 2 são valores associados
# cat file1
e3001 75
n5244 30
w1453 500
#cat file2
d1128 30
w1453 515
n5244 30
e3001 55
Coisas a considerar.
- userIds podem não ser classificados exatamente em ambos os arquivos
- O número de userIds pode variar nos arquivos
REQUERIDOS
- em primeiro lugar, o userId do arquivo1:column1 deve corresponder ao UserId no arquivo2:column1
- em seguida, compare seus valores em file1:column2 com file2:column2
- print onde os valores tem variância. também userIds extras, se houver
RESULTADO:
e3001 has differnece, file1 value: 75 & file2 value: 55
w1453 has differnece, file1 value: 500 & file2 value: 515
d1128 is only present in filename: file1|file2
solução com 1liner-awk ou loop bash é bem-vinda
Estou tentando fazer um loop, mas está cuspindo lixo, acho que há algum erro de lógica
#!/usr/bin/env bash
## VARIABLES
FILE1=file1
FILE2=file2
USERID1=(`awk -F'\t' '{ print $1 }' ${FILE1}`)
USERID2=(`awk -F'\t' '{ print $1 }' ${FILE2}`)
USERDON1=(`awk -F'\t' '{ print $2 }' ${FILE1}`)
USERDON2=(`awk -F'\t' '{ print $2 }' ${FILE2}`)
for user in ${USERID1[@]}
do
for (( i = 0; i < "${#USERID2[@]}"; i++ ))
#for user in ${USERID2[@]}
do
if [[ ${USERID1[$user]} == ${USERID2[i]} ]]
then
echo ${USERID1[$user]} MATCHES BALANCE FROM ${FILE1}: ${USERDON1[$i]} WITH BALANCE FROM ${FILE2}: ${USERDON2[$i]}
else
echo ${USERID1[$user]}
fi
done
done
Abaixo está o arquivo copiado diretamente da caixa linux. É separado por tab, mas o awk também funciona com tab, até onde eu sei.
#cat file1
e3001 55
n5244 30
w1453 515
Hmmm - seu roteiro segue a rota cênica, por assim dizer. Que tal uma abordagem simples
awk
? CurtiEle lê todo o arquivo1 em um array, então, com cada linha no arquivo2, verifica
$1
os índices do array e, se presente, imprime a diferença (ou não imprime se não houver), edelete
é o elemento do array (quedelete
pode ser ausente em algumas implementações awk, BTW). Se não estiver presente, imprima em conformidade. NaEND
seção, todos os elementos restantes da matriz são impressos, pois existem apenas no arquivo1.O shell é uma ferramenta horrível para esse tipo de coisa. Além disso, como regra geral, você deve evitar CAPS para suas variáveis de shell em seus scripts de shell. Como, por convenção, as variáveis de shell do ambiente global são capitalizadas, isso pode levar a colisões de nomenclatura e problemas difíceis de depurar. Finalmente, seu script requer a leitura do arquivo 4 vezes separadas (!) e o processamento dos dados.
Com isso dito, aqui está outra abordagem awk (francamente, a de RudiC é melhor, mas eu já escrevi isso, então estou postando de qualquer maneira):
Os comentários são autoexplicativos:
Essencialmente a mesma solução postada por RudiC, mas sem todos os nomes de variáveis em maiúsculas e com algumas outras pequenas melhorias para clareza: