Como imprimir colunas com awk e ao mesmo tempo editar apenas uma coluna?

1

Ainda no nível de iniciante!

Exemplo de uma linha no meu file.txt :

158.45.456.756 - - [04/Feb/2016:10:51:24 -0500] "GET /tiles/1.0.0/cd/base/1/85/785.png?wb75678545=75D2503E HTTP/1.1" 200 8848 "http://site/map.html" "Mozilla/5.0 (Windows NT 6.1; MOM64; Trident/7.0; mv:10.0) like Blah"

Resultado Eu quero cumprir :

[04/Feb/2016:10:51:24-0500]/tiles/1.0.0/cd/base/1/85/7852008848

O que tentei até agora

awk '{ print }' retornará:

[04/Feb/2016:10:51:24-0500]/tiles/1.0.0/cd/base/1/85/785.png?wb75678545=75D2503E2008848

o que não é bom porque esta parte .png?wb75678545=75D2503E não deve estar contida na linha.

Eu também tentei apenas imprimir a 7ª coluna e excluir tudo após o último ponto com awk '{ print }' | grep -Po '.*(?=\.)' , o que me retornou o resultado desejado para uma coluna específica:

/tiles/1.0.0/cd/base/1/85/785

no entanto acabo ficando de fora com outra parte da linha.

Pergunta

Como posso imprimir todas as colunas de que preciso e ao mesmo tempo ou antes de editar apenas a 7ª coluna?

    
por vayacondios2015 07.10.2016 / 20:49

1 resposta

2

com awk :

awk '{print   gensub("(.*/[^.]+)\..*", "\1", 1, )  }' 
  • print imprime os campos obrigatórios sem qualquer modificação, com apenas a parte obrigatória do sétimo campo sendo extraída com gensub()

  • Em gensub("(.*/[^.]+)\..*", "\1", 1, ) , o padrão Regex "(.*/[^.]+)\..*" corresponde à parte anterior ao . após o último / e coloca isso no grupo capturado 1 e, em seguida, o restante como correspondências por% código%. Na substituição apenas o grupo capturado é usado para obter apenas essa parte

  • No padrão Regex \..* , a parte dentro do grupo capturado (.*/[^.]+)\..* , ou seja, em () , .*/[^.]+ corresponde com avidez até o último .*/ , então / corresponde à parte até o próximo [^.]+ , isso é mantido como grupo capturado 1, já que essa é a parte desejada, e usaremos o grupo em substituição, então . corresponde a um literal \. , então . corresponde ao restante da string

Do comentário, se você quiser manter .* dentro da correspondência, ou seja, . também:

awk '{print   gensub("(.*/[^.]+\.).*", "\1", 1, )  }' 

Exemplo:

% awk '{print   gensub("(.*/[^.]+)\..*", "\1", 1, )  }' <<<'158.45.456.756 - - [04/Feb/2016:10:51:24 -0500] "GET /tiles/1.0.0/cd/base/1/85/785.png?wb75678545=75D2503E HTTP/1.1" 200 8848 "http://site/map.html" "Mozilla/5.0 (Windows NT 6.1; MOM64; Trident/7.0; mv:10.0) like Blah"'
[04/Feb/2016:10:51:24-0500]/tiles/1.0.0/cd/base/1/85/7852008848

% awk '{print   gensub("(.*/[^.]+\.).*", "\1", 1, )  }' <<<'158.45.456.756 - - [04/Feb/2016:10:51:24 -0500] "GET /tiles/1.0.0/cd/base/1/85/785.png?wb75678545=75D2503E HTTP/1.1" 200 8848 "http://site/map.html" "Mozilla/5.0 (Windows NT 6.1; MOM64; Trident/7.0; mv:10.0) like Blah"'
[04/Feb/2016:10:51:24-0500]/tiles/1.0.0/cd/base/1/85/785.2008848
    
por heemayl 07.10.2016 / 20:58