Primeira variante simples, mas limitada
VAR3=$(printf "%d\n" $VAR1 $VAR2 | sort | uniq -u | tr '\n' ' ' | sed 's/\s$//)
$ echo "$VAR3"
2 4
A principal falha é: ele deixa apenas valores únicos da variável VAR1
. Ou seja, se $VAR1
tiver um valor repetido algumas vezes, esse valor não aparecerá no $VAR3
, porque não é exclusivo.
Exemplo:
VAR1="1 2 2 3 4 4 4 5"
VAR2="1 3 5"
# the resulting VAR3 variable is empty
VAR3 = "" # because it is containing only unique values and '2' and '4' repeated few times in the 'VAR1', therefore, they are not unique.
# The right result should be
VAR3 = "2 2 4 4 4"
Segunda variante, mais universal e correta
VAR3=$(printf "%s\n" $VAR2 | awk -v var1="$VAR1" '
{arr2[$1] = 1;}
END {
size = split(var1, arr1);
for(i = 1; i <= size; i++) {
if(!arr2[arr1[i]])
printf "%s ", arr1[i];
}
}' | sed 's/\s$//')
Explicação
-
printf "%s\n" $VAR2
- converte o$VAR2
para a coluna - um valor por linha. -
awk ...
- remove os valores de$VAR2
de$VAR1
.-
{arr2[$1] = 1;}
- coloca todos os valores deVAR2
(eles são canalizados paraawk
porprintf
) na matriz, onde os valores se tornam os índices da matriz. O= 1
significa apenas true - esse valor existe. Esse truque nos dá o próximo comportamento: a ocorrência do primeiro valor cria o elemento array, então, se o mesmo valor aparecer novamente, ele vai para o mesmo índice de array, ou seja, o item não muda, quando o mesmo valor aparece algumas vezes . Assim, no final, estamos tendo todos os valores exclusivos da variávelVAR2
. SeVAR2="one three five"
, entãoarr2
será:arr2[one] = 1, arr2[three] = 1, arr2[five] = 1
. -
END { size = split(var1, arr1);
- quando as linhas de entrada terminaram (VAR2
processamento concluído), estamos dividindo oVAR1
na matriz - cada valor vai para o item separado. SeVAR1="one two three four five"
, então, obteremos a seguinte matriz:arr1[1] = one, arr1[2] = two, arr1[3] = three ...
, e assim por diante. A funçãosplit
retorna o tamanho da nova matriz criada. -
if(!arr2[arr1[i]]) printf "%s ", arr1[i];
- então, itera através dearr1
itens e verifica searr2
tem índice para este item. Por exemplo:i = 1; arr1[1] = "one"
thenarr2[arr1[i]]
é isso -arr2[one]
. Este item existe, não imprima. %código%. Oi = 2; arr1[2] = "two"
não existe, portanto imprima-o. Assim, estamos imprimindo todos os valores doarr2[two]
, que não aparecem noarr1
.
-
-
arr2
- remove o espaço à direita.
Prós deste caminho em comparação com a primeira variante:
# It can process strings
VAR1="one two three four five"
VAR2="one three five"
# the resulting VAR3 variable
VAR3 = "two four"
# It doesn't remove multiple occurrence of one value in the VAR1
VAR1="1 2 2 3 4 4 4 5"
VAR2="1 3 5"
# the resulting VAR3 variable
VAR3 = "2 2 4 4 4"