Subtrair valores de dois arquivos

1

Suponha que eu tenha dois arquivos como abaixo e gostaria de subtrair os valores de dois arquivos: -

Arquivo 1 -

emcas_bdl_migrate=2
emcas_biaas_dev=691
emcas_brs_ba=462
emcas_cc_analytics=1985
emcas_clm_reporting=0
emcas_collab_xsat=3659
emcas_cpsd_cee=10
emcas_cpsd_hcp=0
emcas_e2ep_ba=81
emcas_edservices_bi=643

E Arquivo 2 -

emcas_bdl_migrate=2
emcas_biaas_dev=63
emcas_brs_ba=430
emcas_cc_analytics=2148
emcas_clm_reporting=16
emcas_collab_xsat=4082
emcas_cpsd_cee=11
emcas_cpsd_hcp=0
emcas_cs_logistics=0
emcas_e2ep_ba=195
emcas_edservices_bi=1059

Pode haver valores extras para o Arquivo 2 (por exemplo, emcas_cs_logistics=0 no segundo arquivo extra). Que será mesclado no arquivo de saída final.

Quer uma saída desejada como Arquivo 3 -

emcas_bdl_migrate=0
emcas_biaas_dev=-628
emcas_brs_ba=-32
emcas_cc_analytics=163
emcas_clm_reporting=16
emcas_collab_xsat=423
emcas_cpsd_cee=11
emcas_cpsd_hcp=0
emcas_cs_logistics=0
emcas_e2ep_ba=-114
emcas_edservices_bi=416
    
por Subhashis Dey 03.10.2018 / 14:11

4 respostas

0

Aqui está uma abordagem usando Python. Observe que esse é um caso clássico para a coleção do Contador

#!/usr/bin/env python3

import argparse
from collections import Counter

def read(f):
    """Reads the contents of param=value file and returns a dict"""
    d = {}

    with open(f,'r') as fin:
        for item in fin.readlines():
            s = item.split('=')
            d[s[0]] = int(s[1])

    return d

def write(f, d):
    """Writes dict d to param=value file 'f'"""

    with open(f, 'w') as fout:
        for k,v in sorted(d.items()):
            fout.write('{}={}\n'.format(k,v))

def subtract(d1, d2):
    """
    Subtracts values in d2 from d1 for all params and returns the result in result.
    If an item is present in one of the inputs and not the other, it is added to
    result.

    Note: order of arguments plays a role in the sign of the result.
    """
    c = Counter(d1.copy())
    c.subtract(d2)
    return c

if __name__ == "__main__":

    parser = argparse.ArgumentParser()
    parser.add_argument('file1', type=str, help='path to file 1')
    parser.add_argument('file2', type=str, help='path to file 2')
    parser.add_argument('outfile', type=str, help='path to output file')

    args = parser.parse_args()

    d1 = read(args.file1)
    d2 = read(args.file2)

    d3 = subtract(d1,d2)

    write(args.outfile, d3)

Salve o código acima em um arquivo chamado subtract_params e adicione permissões executáveis. Pode então ser chamado como:

subtract_params file1.txt file2.txt result.txt 
    
por 03.10.2018 / 17:51
1

Uma maneira de fazer isso é usar matrizes associativas. Isso aqui:

#!/bin/bash

# Declare a to be an associative array
declare -A a

# Read in file2, populating the associative array
while read l; do
  k=${l%=*}
  v=${l#*=}
  a[${k}]=${v}
done <file2.txt

# Read in file1.  Subtract the value for a key in file1
# from what was populated into the array from file2.
while read l; do
  k=${l%=*}
  v=${l#*=}
  (( a[${k}] -= ${v} ))
done <file1.txt

# Print out the resulting associative array.
for k in ${!a[@]}; do
  echo "${k}: ${a[${k}]}"
done

exit 0
    
por 03.10.2018 / 15:05
1

Você pode usar awk para isso:

awk -F= 'NR==FNR{a[$1]=$2;next}{printf "%s=%s\n",$1,$2-a[$1]}' file1 file2
    
por 03.10.2018 / 15:08
1

Tente também

awk -F= -vOFS="=" 'NR==FNR {T[$1] = $2; next} {$2 -= T[$1]} 1' file[12]
emcas_bdl_migrate=0
emcas_biaas_dev=-628
emcas_brs_ba=-32
emcas_cc_analytics=163
emcas_clm_reporting=16
emcas_collab_xsat=423
emcas_cpsd_cee=1
emcas_cpsd_hcp=0
emcas_cs_logistics=0
emcas_e2ep_ba=114
emcas_edservices_bi=416

Isso coleta os valores do arquivo 1 $ 2 na matriz T indexada pelo token em $ 1. Em seguida, lendo o arquivo2, ele subtrai o respectivo elemento T do valor do arquivo2 (ou 0 se não existir) antes de imprimir. O resultado se desvia em duas posições da saída desejada; talvez você queira verificar novamente se há erros de digitação.

    
por 03.10.2018 / 15:15