如何AWK仅打印特定项目?

时间:2019-06-27 06:39:22

标签: awk

我有一个如下所示的日志文件:

Ã

我已经使用grep通过RPT_ALINKS隔离了我感兴趣的行。在那一行中,我想知道如何使用AWK仅打印以TK结尾的链接。

我真的要运行这个了

RPT_LINKS=1,T1999
RPT_NUMALINKS=1
RPT_ALINKS=1,1999TK,2135,2009,31462,29467,2560
RPT_TXKEYED=1
RPT_ETXKEYED=0

但是我敢肯定,比我聪明的人已经知道我只会收回传统知识,如何获得整个领域,以便获得1999TK的回报?

6 个答案:

答案 0 :(得分:3)

如果该行中只有一个RT,并且RT始终在末尾:

awk '/RPT_ALINKS/{match($0,/[^=,]*TK/); print substr($0,RSTART,RLENGTH)}'

您还可以使用双grep

grep -w 'RPT_ALINKS' stats2.log | grep -wo '[^=,]*TK'

以下sed解决方案也可以很好地工作:

sed '/RPT_ALINKS/s/\(^.*[,=]\)\([^=,]*TK\)\(,.*\)\?/\2/'

答案 1 :(得分:2)

它不再优雅

awk -F '=' '$1=="RPT_ALINKS" {n=split($2,array,",")
            for(i=1; i<=n; i++)
              if (array[i] ~ /TK$/)
                {print array[i]}}
           ' stats2.log
  

n=split($2,array,","):将1,1999TK,2135,2009,31462,29467,2560,拆分为数组arrayn包含许多数组元素,此处为7。

答案 2 :(得分:2)

这是一个简单的解决方案

awk -F ',|=' '/^RPT_ALINKS/ { for (i=1; i<=NF; i++) if ($i ~ /TK$/) print $i }' stats2.log

它仅显示在以RPT_ALINKS开头的记录上。并在那里检查每个字段。如果字段以TK结尾,则将其打印出来。

答案 3 :(得分:1)

Dang,我正准备发布double-grep替代方法,但被挖了。并且所有好的awk解决方案也都采用了。

S。因此,我们在这里进行娱乐活动。

$ mapfile a < stats2.log
$ for i in "${a[@]}"; do [[ $i =~ ^RPT_ALINKS=(.+,)*([^,]+TK) ]] && echo "${BASH_REMATCH[2]}"; done
1999TK

它的缺点是运行方式比awk慢,并且不使用字段。哦,它不会在一行上处理多个*TK项目。就像sed一样,这是将线条处理为样式而不是 fields ,这会降低美观度。通过使用mapfile,我们限制了您可以处理的输入大小,因为整个日志都已加载到内存中。当然,您实际上并不需要这样做,但是如果您要使用管道,则还是要使用其他工具。 :-)

星期四快乐。

答案 4 :(得分:1)

使用针对ERE具有-E的sed,例如GNU或OSX / BSD sed:

$ sed -En 's/^RPT_ALINKS=(.*,)?([^,]*TK)(,.*|$)/\2/p' file
1999TK

使用GNU awk将第三个参数匹配():

$ awk 'match($0",",/^RPT_ALINKS=(.*,)?([^,]*TK),.*/,a){print a[2]}' file
1999TK

答案 5 :(得分:0)

您可以使用其他方法来代替遍历它。
这样会很快,循环需要时间。

awk -F"TK" '/RPT_ALINKS/ {b=split($1,a,",");print a[b]FS}' stats2.log
1999TK

在这里,您可以通过将字段分隔符设置为TK来拆分行,然后搜索包含RPT_ALINKS的行
得到$1=RPT_ALINKS=1,1999$2=,2135,2009,31462,29467,2560
$1将始终在最后一个逗号后具有我们的价值。
因此,请使用逗号分割功能将其分割。 b将包含许多字段。
由于我们知道该数字位于最后一部分,因此我们确实使用a[b]并添加包含FS

TK