Bash 如何在行首用逗号分隔的一个或多个IP中只获取最后一个IP

Bash 如何在行首用逗号分隔的一个或多个IP中只获取最后一个IP,bash,sed,awk,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] ...

我想解析日志文件,我只需要从一个或多个文件中获取最后一个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列中从来没有逗号,这是我的帮助。[日期]之后的下一列中可能会有更多逗号

我曾尝试测试前几列,如果其中有逗号,则删除它们,但问题是,有时有10多个IP

这适用于2个IP:

awk '{if ($1 ~ /,/) {$1=""}; if ($2 ~ /,/) {$2=""}  }1'
我的想法是“如果前面有逗号,请删除逗号之前的所有内容,否则保持不变”。不幸的是,我的sed/awk技能不足以做到这一点

非常感谢你的帮助

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

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

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

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

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


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

行中是否有其他逗号?如果没有,您可以执行以下操作:

awk -F, '{ print $NF }'
这将留下前导空格,如果需要,您可以使用以下任一方法删除前导空格:

awk -F, '{ print $NF }' | sed 's/^ *//'
awk -F, '{ print gensub(/^ */, "", "G", $NF) }'
在awk中,内置变量NF返回输入行上的字段数,因此打印$NF将打印行中的最后一个字段。因此,如果输入行上有更多逗号,则无法获得所需的输出


请注意,单引号的使用非常关键(不要使用双引号,否则$NF将由shell扩展而不是传递给awk)。

行中还有其他逗号吗?如果没有,可以执行以下操作:

awk -F, '{ print $NF }'
这将留下前导空格,如果需要,您可以使用以下任一方法删除前导空格:

awk -F, '{ print $NF }' | sed 's/^ *//'
awk -F, '{ print gensub(/^ */, "", "G", $NF) }'
在awk中,内置变量NF返回输入行上的字段数,因此打印$NF将打印行中的最后一个字段。因此,如果输入行上有更多逗号,则无法获得所需的输出


请注意,单引号的使用非常关键(不要使用双引号,否则$NF将由shell扩展而不是传递给awk)。

谢谢Igor,这是有效的,但是我需要限制它仅在第一次出现[,行的其余部分可以包含我需要保持不变的逗号。Sorrt,它现在不能替换任何内容。您是对的,星号使它起作用,但也更改了行的其余部分。我已将您的第一个回复sed-r“s/^(.*)?(.*)$/\2/”修改为sed-r“s/^(.*)?(.[)/\2/”这似乎是可行的。如果你编辑你的帖子,我会批准它作为可接受的答案。更简单一点:
sed-r的/^([0-9.]+,)+/'
谢谢你Igor,这是可行的,但是我需要限制它仅在第一次出现之前替换逗号[,行的其余部分可以包含我需要保持不变的逗号。Sorrt,它现在不能替换任何内容。您是对的,星号使它起作用,但也更改了行的其余部分。我已将您的第一个回复sed-r“s/^(.*)?(.*)$/\2/”修改为sed-r“s/^(.*)?(.[)/\2/”这似乎是可行的。如果你编辑你的帖子,我会批准它作为可接受的答案。简单一点:
sed-r的/^([0-9.]+,)+/'
谢谢你,但是在[date]列之后的行中可以有更多的逗号。我已经在问题中更新了这一点,对不起。谢谢你,但是在[date]列之后的行中可以有更多的逗号[日期]栏。对不起,我已在问题中更新了此栏。