如何在行的开头只从一个或多个中获取最后一个IP除以逗号

时间:2010-10-28 10:41:14

标签: bash sed awk

我想解析日志文件,我需要在行的开头只获取一个或多个最后一个IP除以逗号:

这是线条的样子:

80.250.5.1 - - [26/Oct/2010:13:10:14 +0200] ...
80.250.5.1, 80.250.5.2 somethingA - [26/Oct/2010:13:10:14 +0200] ...
80.250.5.1, 80.250.5.2, 80.250.5.3 - somethingB [26/Oct/2010:13:10:14 +0200] ...

我需要得到:

80.250.5.1 - - [26/Oct/2010:13:10:14 +0200] ...
80.250.5.2 somethingA - [26/Oct/2010:13:10:14 +0200] ...
80.250.5.3 - somethingB [26/Oct/2010:13:10:14 +0200] ...

注意:在somethingA和somethingB列中永远不会有逗号,这是我的帮助。在[date]之后的下一列中可能会有更多逗号。

我试过测试几个第一列并删除它们,如果有逗号,但问题是有时候有超过10个IP。

这适用于2个IP:

awk '{if ($1 ~ /,/) {$1=""}; if ($2 ~ /,/) {$2=""}  }1'

我的想法是做一些类似“如果之前有逗号[,删除逗号前的所有内容,否则保持不变”。不幸的是,我的sed / awk技能还不够好。

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

sed -r 's/^(([0-9]+\.){3}[0-9]+, )*(.*)$/\3/'

([0-9]+\.){3}[0-9]+)捕获IP地址。

([0-9]+\.){3}[0-9]+, )*重复捕获,直到没有更多地址后跟逗号,这意味着该行的其余部分正是我们需要的(请注意,最后(或唯一)地址是后跟逗号。)

最后一步是指示sed将整个输入行替换为它在第三组括号中捕获的内容(因此在表达式的末尾为\3),这给了我们一个期望的结果。

答案 1 :(得分:0)

该行还有其他逗号吗?如果没有,你可以这样做:

awk -F, '{ print $NF }'

如果需要,这将留下比您可以修剪的前导空格,使用以下任一方法:

awk -F, '{ print $NF }' | sed 's/^ *//'
awk -F, '{ print gensub(/^ */, "", "G", $NF) }'

在awk中,内置变量NF返回输入行上的字段数,因此打印$ NF将打印行中的最后一个字段。因此,如果输入行上有更多逗号,则无法获得所需的输出。

请注意,使用单引号很重要(不要使用双引号,否则$ NF会被shell扩展而不是传递给awk)。