1

Still on beginner level!

Example of one line in my 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"

Result I want to accomplish:

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

What I have tried until now

awk '{ print $4 $5 $7 $9 $10}' will return:

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

which is not good because this part .png?wb75678545=75D2503E shouldnt be contained in the line.

I also tried just printing 7th column and delete everything after last point with awk '{ print $7}' | grep -Po '.*(?=\.)' which returned me result that I want for specific column:

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

however I end up being left out with other part of the line.


Question

How can I print all the columns I need and in the same time or before edit just 7th column?

1 Answer 1

2

With awk:

awk '{print $4 $5 gensub("(.*/[^.]+)\\..*", "\\1", 1, $7) $9 $10}' 
  • print prints the required fields without any modification, with only the required portion of the 7th field being extracted with gensub()

  • In gensub("(.*/[^.]+)\\..*", "\\1", 1, $7), the Regex pattern "(.*/[^.]+)\\..*" matches the portion prior to the . after last /, and put that in captured group 1, and then the rest as matches by \\..*. In the replacement only the captured group is used to get that portion only

  • In Regex pattern (.*/[^.]+)\\..*, the portion inside the captured group () i.e. in .*/[^.]+, .*/ matches greedily upto the last /, then [^.]+ matches the portion upto the next ., this is kept as captured group 1 as this is our desired portion, and we will use the group in replacement, then \\. matches a literal ., then .* matches the rest of the string

From comment, if you want to keep . inside the match i.e. want . too:

awk '{print $4 $5 gensub("(.*/[^.]+\\.).*", "\\1", 1, $7) $9 $10}' 

Example:

% awk '{print $4 $5 gensub("(.*/[^.]+)\\..*", "\\1", 1, $7) $9 $10}' <<<'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 $4 $5 gensub("(.*/[^.]+\\.).*", "\\1", 1, $7) $9 $10}' <<<'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
3
  • thanks for a quick reply. still cant conform does the whole file work because I am having some other difficulties. Can you please explain what does the "(.*/[^.]+)\\..*", "\\1", 1, stands for? How could you be able to delete everything after the point, but leave the point in the line. Oct 7, 2016 at 19:57
  • @vayacondios2015 Check my edits.
    – heemayl
    Oct 7, 2016 at 20:06
  • Thanks for explanation and additional answer! Later on I kind of realized that I need to include a dot also! Oct 7, 2016 at 21:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .