Como salvar variáveis em um script que pode ser compartilhado entre duas execuções do awk em relação ao mesmo arquivo de entrada no script? [fechadas]

3

Eu tenho um arquivo de log, cuja formatação é muito consistente e que eu controlo. Ele produz campos delimitados por canal de comprimento constante.

Dois campos são relevantes para o processo de filtragem que desejo criar, chamando-o de primário e secundário.

Usando o Grep, posso filtrar primeiro no primário. Isso produzirá uma lista incompleta de linhas relevantes. Nesta lista irá mostrar várias linhas, e estas terão um dos dois valores distintos no campo secundário. Também haverá outras linhas que não correspondem ao campo principal, mas cujo campo principal está em branco, que corresponde a um ou a outro dos valores do campo secundário. Todas essas linhas são relevantes. E eu os quero na saída final, mas eu não os conheço até ter passado pelo passe inicial.

Todas as entradas em que o campo secundário corresponde terão o campo primário inicial ou um campo primário em branco. Em nenhum caso, um campo secundário ficará em branco.

Minha estratégia é 1. awk o arquivo de log uma vez, retirando todas as linhas onde o campo primário corresponde (esta será a entrada para o script). Para cada linha, examine o campo secundário até que ambos os valores de campo secundários correspondentes sejam encontrados. 2. awk o logfile novamente, retirando todas as linhas onde o campo primário corresponde ou o campo secundário corresponde a um dos dois valores aprendidos na primeira passagem.

Como posso armazenar os dois valores de campos secundários aprendidos no passe 1 e usá-los ao escrever as condições para o passo 2?

Pediram-me para fornecer amostras, por isso aqui está uma versão simplificada dos dados que ilustram os pontos importantes. "Primário" é o campo 2 e "Secundário" é o campo 3.

Este é o primeiro pull (o valor de entrada é 05478900172)

2015-03-10 09:13:40,598|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,617|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,617|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,626|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,626|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:14:16,686|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,695|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,705|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,705|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,714|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,714|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:23,838|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,878|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,878|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|   0
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,888|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,888|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:15:01,915|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,936|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,936|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,945|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,946|05478900172|4792761 | 17|s|D|S|----

A partir disso, podemos ver que o campo secundário ($ 3) contém dois valores possíveis para este campo primário (4792761 ou 4792964).

Queremos que o nosso script extraia o seguinte conjunto de dados, que contém todos os registros com 05478900172 em $ 2 e (4792761 ou 4792964) em $ 3. Eu não sei esses dois valores até que eu tenha feito a varredura inicial, então eu preciso passar esses valores como variáveis que de alguma forma são compartilhadas entre a primeira e a segunda passagem.

2015-03-10 09:13:40,598|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,601|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,608|       null|4792761 |---|-|K|-|----
2015-03-10 09:13:40,608|       null|4792761 |---|-|K|-|----
2015-03-10 09:13:40,617|       null|4792761 |---|r|D|S|----
2015-03-10 09:13:40,617|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,617|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,626|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:13:40,626|05478900172|4792761 | 15|s|D|S|----
2015-03-10 09:14:16,686|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,694|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,695|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,696|       null|4792964 |---|-|K|-|----
2015-03-10 09:14:16,696|       null|4792964 |---|-|K|-|----
2015-03-10 09:14:16,704|       null|4792964 |---|r|D|S|----
2015-03-10 09:14:16,705|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,705|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,714|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,714|05478900172|4792964 | 41|s|D|S|----
2015-03-10 09:14:16,760|       null|4792964 |---|r|D|S|----
2015-03-10 09:14:16,760|       null|4792964 |---|r|D|S|----
2015-03-10 09:14:23,817|       null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,817|       null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,817|       null|4792964 | 42|-|D|S|7057
2015-03-10 09:14:23,817|       null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,818|       null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,818|       null|4792964 | 42|-|D|S|----
2015-03-10 09:14:23,838|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,876|       null|4792964 |---|-|K|-|----
2015-03-10 09:14:23,876|       null|4792964 |---|-|K|-|----
2015-03-10 09:14:23,878|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,878|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,878|       null|4792964 |---|r|D|S|----
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,879|       null|4792964 |---|r|D|S|----
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|   0
2015-03-10 09:14:23,879|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,888|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:14:23,888|05478900172|4792964 | 43|s|D|S|----
2015-03-10 09:15:01,915|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,917|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,925|       null|4792761 |---|-|K|-|----
2015-03-10 09:15:01,925|       null|4792761 |---|-|K|-|----
2015-03-10 09:15:01,936|       null|4792761 |---|r|D|S|----
2015-03-10 09:15:01,936|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,936|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,945|05478900172|4792761 | 17|s|D|S|----
2015-03-10 09:15:01,946|05478900172|4792761 | 17|s|D|S|----
    
por Steve Cohen 10.03.2015 / 20:14

2 respostas

1

Como solicitado pelo @KM, aqui está minha resposta.

#! /bin/sh

# this script pulls all rows from a log that are directly or 
# indirectly related to a given session id.  Session IDs are stored
# in $2 of each row.  This field may be null.  Directly related
# rows are those with $2 matching the supplied parameter.  Indirectly
# related rows are those with $3 (aka xid) matching $3 in some other 
# row where $2 matches the supplied parameter.
# It may be assumed that for any rows with the same $3, 
# the $2 field will be identical or null.


SESS_SRCH="$1"
if [ -z $2 ]
then 
 LOGFILE=/path/to/default/log
else 
 LOGFILE=$2
fi

# pass 1:
# read the logfile once to find all unique XIDs associated
# with the supplied session ID ($SESS_SRCH)

XIDS=$(awk -F\| -v sessid="$1" '$2 ~ sessid { xids[$3]=0 } 
END{ 
    for (xid in xids) { 
        print xid 
    } 
}' < ${LOGFILE}
)

XID_SRCH=""

#build a search string from these xids to form a new search string.
for XID in $XIDS
do
 XID_SRCH="${XID_SRCH}|${XID}" 
done

#strip off the leading "|"
XID_SRCH=${XID_SRCH:1}

# pass 2
# read the logfile again, this time seaching on $3, for any of the
# xids found in pass 1.
awk -F\| -v search="$XID_SRCH" '$3 ~ search { print }' < ${LOGFILE}
    
por 11.03.2015 / 15:29
0

Este é um trecho de código que deve fazer o que você está perguntando, embora pareça que existe um problema lógico, já que a saída deste loop é idêntica com ou sem o segundo teste, já que o resultado ocorrerá Tempo. Eu estou supondo que você precisa fazer um teste mais complexo na segunda execução do awk do que você descreveu.

O que este snippet faz é primeiro extrair todas as linhas no arquivo de dados que correspondem ao campo 2 com 'PATTERN' extraindo campo 3, então usando sort e uniq eliminar duplicatas do campo 3. Que é então executado em um loop while para cada uniq campo 3 valores (4792761 ou 4792964), mas desta vez testando tanto o campo 2 contra PADRÃO quanto o campo 3 contra os valores em loop.

PATTERN="05478900172"

awk -F\| -v matchpat="$PATTERN" '$2 ~ matchpat {print $3}' | sort | uniq | while read field 
do 
   awk -F\| -v matchpat=$PATTERN -v secondpat="$field" '$2 ~ matchpat { if ( $3 ~ secondpat ) {print $0}}' datafile
done

Agora eu estou supondo que você realmente quer fazer algo mais complexo do que você descreveu porque você poderia simplificar isso e eliminar o loop while apenas classificando a saída do primeiro comando awk usando o campo 3 como uma chave de ordenação.

    
por 10.03.2015 / 21:56