如何使用 awk 打印列并同时只编辑一列?

如何使用 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打印所需字段而不进行任何修改,只提取第 7 个字段的所需部分,gensub()

  • 在 中gensub("(.*/[^.]+)\\..*", "\\1", 1, $7),正则表达式模式匹配倒数第二"(.*/[^.]+)\\..*"部分之前的部分,并将其放入捕获组中,然后将其余部分作为匹配项。在替换中,仅使用捕获组来获取该部分./1\\..*

  • 在正则表达式模式中(.*/[^.]+)\\..*,捕获组内的部分,()即,贪婪地匹配到最后一个,然后匹配到下一个部分,这被保留为捕获组 1,因为这是我们想要的部分,我们将使用组 in 替换,然后匹配文字,然后匹配字符串的其余部分.*/[^.]+.*//[^.]+.\\...*

从评论中,如果你想继续.参加比赛,.也想:

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

相关内容