extrai, recortar, processar strings em um script bash

1

Eu tenho basicamente 4 arquivos txt com registros como

FILE 1

localhost_access_2018-07-19.tar.gz:13

localhost_access_2018-07-20.tar.gz:17

localhost_access_2018-07-21.tar.gz:12

localhost_access_2018-07-22.tar.gz:4

localhost_access_2018-07-23.tar.gz:2

localhost_access_2018-07-24.tar.gz:2905

localhost_access_2018-07-25.tar.gz:10440

localhost_access_2018-07-26.tar.gz:2644

localhost_access_2018-07-27.tar.gz:1896

localhost_access_2018-07-28.tar.gz:1238

localhost_access_2018-07-29.tar.gz:932


FILE 2

localhost_access_2018-06-19.tar.gz:0

localhost_access_2018-06-20.tar.gz:0

localhost_access_2018-06-21.tar.gz:1

localhost_access_2018-06-22.tar.gz:0

localhost_access_2018-06-23.tar.gz:0

localhost_access_2018-06-24.tar.gz:0

localhost_access_2018-06-25.tar.gz:0

localhost_access_2018-06-26.tar.gz:1

localhost_access_2018-06-27.tar.gz:0

localhost_access_2018-07-04.tar.gz:2

localhost_access_2018-07-05.tar.gz:3

localhost_access_2018-07-06.tar.gz:6

localhost_access_2018-07-07.tar.gz:0

localhost_access_2018-07-19.tar.gz:15

etc.

cada um dos 4 arquivos tem datas redundantes, como neste caso localhost_access_2018-07-19.tar.gz:15 , mas números finais diferentes (após o:).

Para as mesmas datas, eu tenho que: cortar " local_host_access_ " deixando apenas a data em um único arquivo txt novo (sem alterá-lo em valor e formato), e eu tenho que cortar .tar.gz.

Além disso, tenho que somar cada um dos valores para as datas que são as mesmas:

Portanto, se houver 4 datas "localhost_access_2018-07-19" nos 4 arquivos diferentes, eu tenho que somar cada um dos números XYZ após o valor .gz: "XYZ".

Exemplo:

localhost_access_2018-07-19.tar.gz:1

localhost_access_2018-07-19.tar.gz:2

localhost_access_2018-07-19.tar.gz:3

localhost_access_2018-07-19.tar.gz:4

deve retornar na única saída de texto, em um novo arquivo

2018-07-19:10

Eu coloquei minha tentativa como resposta , mas gostaria de receber melhores soluções (e explicações) . Obrigado.

    
por llllIIIIIllllllIIIIIIlllII 17.10.2018 / 18:36

4 respostas

1

Experimente também esta abordagem simples de awk :

awk -F"[_.:]" '                                 # set field separator to "_", ".", or ":"
        {SUM[$3] += $NF                         # sum all trailing fields in array indexed by the date
        }
END     {for (s in SUM) print s, SUM[s]         # print the date and the respective sum
        }
' OFS=":" file[123]                             # set output field separator; have shell expand file names 1 - 3
    
por 17.10.2018 / 23:31
0
awk -F 'localhost_access_' ' 
    {
         n=substr($2,1+index($2,":"));  
         gsub(".tar.gz.*","",$2);
         str[$2]+=n
    }
    END{
        for (i in str){
            print i":"str[i]
        }
    }' node1.txt node2.txt node3.txt node4.txt | sort -to > output.txt

    output_not_sorted=$(cat output.txt);

    # sort output by date

    exit

Deixe-me saber se isso pode ser melhorado.

    
por 18.10.2018 / 10:54
0

Dados os dois arquivos que você mostra no início de sua pergunta e assumindo que eles não contêm linhas em branco:

$ awk -F ':' -v OFS=':' '
    { sum[$1]+=$2 }
    END { for (key in sum) {
        split(key,f,"[_.]")
        print f[3],sum[key] } }' file* | sort
2018-06-19:0
2018-06-20:0
2018-06-21:1
2018-06-22:0
2018-06-23:0
2018-06-24:0
2018-06-25:0
2018-06-26:1
2018-06-27:0
2018-07-04:2
2018-07-05:3
2018-07-06:6
2018-07-07:0
2018-07-19:28
2018-07-20:17
2018-07-21:12
2018-07-22:4
2018-07-23:2
2018-07-24:2905
2018-07-25:10440
2018-07-26:2644
2018-07-27:1896
2018-07-28:1238
2018-07-29:932

Use o nome do arquivo como chave em uma matriz associativa chamada sum e colete a soma de cada nome de arquivo. No final, percorra as teclas sum e imprima a parte da data de cada chave junto com a soma. A parte da data da chave é o terceiro campo após a divisão em pontos e sublinhados.

O resultado é o canalizado embora sort .

Mais curto, mas essencialmente o mesmo que o anterior (mas usa apenas a data como chave na matriz sum ):

awk -F '[_.:]' -v OFS=':' '
    { sum[$3]+=$6 }
    END { for (d in sum) print d, sum[d] }' file*
    
por 23.10.2018 / 21:34
0
#!/bin/bash
# Sum duplicate row values with awk ; Columns 3 and 6
awk -F '[_.:]' '{seen[$3]+=$6}END{for (i in seen) print i, seen[i]}' OFS=":" node[1-4].txt | 

sort > log.txt

Fonte para "# Soma valores de linha duplicados com awk" link

    
por 17.10.2018 / 20:35