我有一个如下所示的日志文件:
Ã
我已经使用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的回报?
答案 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
与,
拆分为数组array
。n
包含许多数组元素,此处为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