Как печатать столбцы с помощью awk и одновременно редактировать только один столбец?

Все еще на начальном уровне!

Пример одной строки в моем 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"

Результат, который я хочу достичь:

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

Что я пробовал до сих пор

awk '{ print $4 $5 $7 $9 $10}' вернусь:

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

что не хорошо, потому что эта часть .png?wb75678545=75D2503E не должны содержаться в строке.

Я также попытался просто напечатать 7-й столбец и удалить все после последней точки с помощью awk '{ print $7}' | grep -Po '.*(?=\.)' который вернул мне результат, который я хочу для конкретного столбца:

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

однако я остаюсь в стороне от другой части линии.


Вопрос

Как я могу напечатать все нужные мне столбцы и одновременно или до редактирования только 7-го столбца?

1 ответ

Решение

С awk:

awk '{print $4 $5 gensub("(.*/[^.]+)\\..*", "\\1", 1, $7) $9 $10}' 
  • print печатает обязательные поля без каких-либо изменений, при этом извлекается только необходимая часть седьмого поля с gensub()

  • В gensub("(.*/[^.]+)\\..*", "\\1", 1, $7), шаблон регулярных выражений "(.*/[^.]+)\\..*" соответствует части до . после последнего /и поместите это в захваченную группу 1, а затем все остальное как \\..*, В замене только захваченная группа используется, чтобы получить только эту часть

  • В шаблоне Regex (.*/[^.]+)\\..*часть внутри захваченной группы () то есть в .*/[^.]+, .*/ соответствует жадно до последнего /, затем [^.]+ соответствует части до следующей ., это сохраняется как захваченная группа 1, так как это наша желаемая часть, и мы будем использовать группу вместо, затем \\. соответствует буквальному ., затем .* соответствует остальной части строки

Из комментария, если вы хотите сохранить . внутри матча т.е. хочу . тоже:

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

Пример:

% 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
Другие вопросы по тегам