Extraia o valor de FILENAME no awk e use-o como um novo campo

1

Estou trabalhando no arquivo CSV chamado Event_42417555_2018-05-23_16\:45\:28-log.txt e formatado assim:

timestamp;fullpath;event;size
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_OPEN;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_ACCESS;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_CLOSE_NOWRITE;2324
1521540649.02;/home/workdir/quad_list_14.json;IN_OPEN;2160
1521540649.03;/home/workdir/quad_list_14.json;IN_ACCESS;2160
1521540649.03;/home/workdir/quad_list_14.json;IN_CLOSE_NOWRITE;2160

O que eu quero é adicionar uma coluna a este arquivo com base em um valor no nome do arquivo extraído com regex [0-9]{8} (e remover o cabeçalho).

1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_OPEN;2324;42417555
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_ACCESS;2324;42417555
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_CLOSE_NOWRITE;2324;42417555
1521540649.02;/home/workdir/quad_list_14.json;IN_OPEN;2160;42417555
1521540649.03;/home/workdir/quad_list_14.json;IN_ACCESS;2160;42417555
1521540649.03;/home/workdir/quad_list_14.json;IN_CLOSE_NOWRITE;2160;42417555

Com as ferramentas do gnu, é fácil que seja assim (mal testado e quase certo de que há um problema com aspas de alguma forma):

#!/bin/bash
#$1 being the filename
JOBID=$(grep -oE "[0-9]{8}" "${1}")
sed -E "s/(.*)/;$JOBID/" "${1}"

Eu quero conseguir isso em awk até agora aqui o que funcionou o melhor :

awk -F";"  'JOBID=substr(FILENAME ,match(FILENAME,"[0-9]{8}"),8); \  
BEGIN { OFS=";"} { if ($1 != "timestamp") print $0,JOBID; }' \  
Event_42417555_2018-05-23_16\:45\:28-log.txt | head

timestamp;fullpath;event;size
timestamp;fullpath;event;size
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_OPEN;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_OPEN;2324;42417555
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_ACCESS;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_ACCESS;2324;42417555
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_CLOSE_NOWRITE;2324
1521540649.02;/home/workdir/ScienceXMLIn/config.cfg;IN_CLOSE_NOWRITE;2324;42417555

Eu tenho minha variável e configurada corretamente, mas não consigo encontrar a posição correta para ela.
Se eu mover o JOBID=substr(FILENAME ,match(FILENAME,"[0-9]{8}"),8);
Não consigo acessar a variável.
O problema aqui é que o arquivo é processado duas vezes, um corretamente (embora minha condição seja ignorada) e o outro onde ele considerou minha variável

    
por Kiwy 24.05.2018 / 13:50

1 resposta

5

Como é uma propriedade de cada arquivo, você deve calcular JOBID ao processar a primeira linha de qualquer arquivo, ou seja, quando FNR for 1:

awk -F";" 'BEGIN { OFS = FS }
FNR == 1 { JOBID=substr(FILENAME, match(FILENAME, "[0-9]{8}"), 8); print }
FNR > 1 { print $0, JOBID }' \
Event_42417555_2018-05-23_16\:45\:28-log.txt | head

Existem várias maneiras de extrair uma correspondência para uma expressão regular; Eu normalmente usaria match em uma matriz:

awk -F";" 'BEGIN { OFS = FS }
FNR == 1 { match(FILENAME, "([0-9]{8})", a); JOBID = a[1]; print }
FNR > 1 { print $0, JOBID }' \
Event_42417555_2018-05-23_16\:45\:28-log.txt | head

idealmente com algum tratamento de erros. Isso usa match para procurar texto correspondente a [0-9]{8} e extrai todos os valores correspondentes na matriz a ( match procura grupos, daí os parênteses adicionados).

Outra abordagem que deve funcionar em qualquer implementação do AWK é dividir o nome do arquivo em sublinhados:

awk -F";" 'BEGIN { OFS = FS }
FNR == 1 { split(FILENAME, a, "_"); JOBID = a[2]; print }
FNR > 1 { print $0, JOBID }' \
Event_42417555_2018-05-23_16\:45\:28-log.txt | head

A saída duplicada em sua versão acontece porque JOBID=substr(FILENAME ,match(FILENAME,"[0-9]{8}"),8) é uma expressão completa com o mesmo peso de qualquer outra em seu programa AWK, com um bloco implícito ( i.e. print ); ele sempre corresponde, porque JOBID é sempre não vazio e não um valor numérico igual a zero, portanto, seu bloco é sempre processado.

    
por 24.05.2018 / 14:03