Expandindo o awk -v variable

2

Quando executo o awk '/2017-12-05T12:07:33.941Z/{y=1;next}y' file.json , ele funciona como esperado, imprimindo tudo após o registro de data e hora.

Estou tentando seguir a sintaxe neste Q / A

awk -v last_log="$last_log" '/{print last_log}/{y=1;next}y' file.txt

Também tentando:

awk -v last_log="$last_log" '/$0 ~ last_log/{y=1;next}y' file.txt

Exemplo, dada a seguinte entrada, retorna todos os logs após o último processamento ( 2017-12-05T12:07:33.941Z ):

{ "name": "PeriodicWork", "hostname": "myHost", "pid": 12189, "level": 20, "msg": "Executing [CheckFailedTask NodeId=8]", "time": "2017-12-05T10:07:33.941Z", "v": 0 }

{ "name": "PeriodicWork", "hostname": "myHost", "pid": 12188, "level": 50, "msg": "Executing [CheckFailedTask NodeId=8]", "time": "2017-12-05T12:07:33.941Z", "v": 0 }

{ "name": "PeriodicWork", "hostname": "myHost", "pid": 12187, "level": 40, "msg": "Executing [CheckFailedTask NodeId=8]", "time": "2017-12-05T12:57:33.941Z", "v": 0 }
    
por Philip Kirkbride 05.12.2017 / 16:24

2 respostas

3

Aqui, não acho que foi sua intenção tratar 2017-12-05T12:07:33.941Z como um regexp (onde . corresponderia a qualquer caractere em vez de apenas . ).

Para uma correspondência de substring, ao contrário de uma correspondência de expressão regular, você pode usar index() :

LAST_LOG="$last_log" awk 'index($0, ENVIRON["LAST_LOG"]) {y=1;next};y' file.txt

Eu prefiro ENVIRON over -v como -v manipula o conteúdo da variável se contiver barras invertidas ( como já foi observado no Q & A que você referenciou ).

Sobre o motivo da sua falha:

/{print last_log}/

como condição , corresponde a registros que correspondem à expressão regular {print last_log} , mas essa não é uma expressão regular válida ( { é um operador regexp que precisa ser usado como {2} ou {1,5} ...).

Em:

/$0 ~ last_log/

novamente, que tenta corresponder em $0 ~ last_log como um regexp. Aqui, isso significa que as linhas que contêm 0 ~ last_log após o final da linha ( $ ), nunca serão correspondidas. Você provavelmente quis dizer:

awk -v last_log="$last_log" '$0 ~ last_log {y=1;next};y' file.txt

É aí que a condição é a expressão $0 ~ last_log , em oposição a apenas uma regexp /foo/ . /foo/ é a abreviação de $0 ~ /foo/ , que corresponde à foo regexp do registro completo.

Você pode fazer $0 ~ var , mas não pode fazer var sozinho, pois não seria uma correspondência de expressão regular, mas uma expressão que será resolvida como verdadeira se var contiver um número diferente de 0 ou uma string não numérica não vazia (como para o seu y one)

    
por 05.12.2017 / 16:35
0

Com intervalos de awk

Do last_log ao eof também pode ser obtido pelo operador ",";

 awk  '$0 ~ last, 0'  last="$last_log" file.txt

Com valores last_log como o apresentado

 awk "/$last_log/,0" file.txt

Provavelmente precisamos adicionar | tail -n +1

Com Sed:

sed  "1,/$last_log/d"  file.txt
    
por 05.12.2017 / 16:50

Tags