0

假设我有很多 ip 号码(每行 2 个 ip 号码,用空格分隔)要查看(这里有两行):

67.21.89.48.1623 139.91.131.115.110
211.47.82.64 139.91.134.123.445

其中一个可能没有端口,因此周期数永远不会一致。我只想要第一个的 ip 号(没有端口)和第二组的端口(没有 ip 号)。所以它应该看起来像:

67.21.89.48 110
211.47.82.64 445

或者它可能看起来像这样:

67.21.89.48.110
211.47.82.64.445

只要我知道IP和端口的位置,这并不重要。

我一直在使用这样的东西:

cut -d'.' -f1-4,9 < file.txt

但这仅适用于一致数量的周期。有什么办法可以从后面剪掉吗?

4

2 回答 2

3

详细格式:

perl -n -e 'print "$1 $2\n" if m/^
                                 ((?:\d+\.){3}\d+)      # IPv4 address
                                 (?:\.\d+)?             # Optional port
                                 \s+                    # White space
                                 (?:(?:\d+\.){4})       # IPv4 address plus dot
                                 (\d+)                  # Port number
                                 \s*$                   # Optional white space
                                /x' perl.data

单线:

perl -ne 'print "$1 $2\n" if m/^((?:\d+\.){3}\d+)(?:\.\d+)? (?:(?:\d+\.){4})(\d+)\s*$/'

如果第二个条目有端口号,这只会打印任何内容;如果没有,则跳过该行。

如果您愿意,可以使 IP 地址和端口号识别对称(即使不会打印第二个 IP 地址):

perl -n -e 'print "$1 $4\n" if m/^ \s*                  # Optional white space
                                 ((?:\d+\.){3}\d+)      # IPv4 address
                                 (?:\.(\d+)) ?          # Optional Port number
                                 \s+                    # White space
                                 ((?:\d+\.){3}\d+)      # IPv4 address
                                 (?:\.(\d+))            # Mandatory Port number
                                 \s* $                  # Optional white space
                                /x' perl.data

我用过\d+“一个或多个数字”;对于IPv4点分十进制地址组件,可以做成\d{1,3}“一到三位数”,端口号可以做成\d{1,5}“一到五位数”。

如果你真的很注重细节,你甚至可以更精确地限制数字范围,但这可能不值得。这是正则表达式处理的一个共同特征;您可以制作出足以胜任手头工作的东西 - 不必处理恶意软件可能向您抛出的所有可能变化。你必须对要做什么做出判断。

于 2012-04-24T21:42:59.273 回答
2

正如 Jonathan 在评论中指出的那样,使用cut会非常复杂,因为您需要的列数可能会有所不同。

这是一个示例sed

$ echo "67.21.89.48.1623 139.91.131.115.110
211.47.82.64 139.91.134.123.445" | sed -r 's/^(([0-9]{1,3}\.){3}[0-9]{1,3})(.*)\.([0-9]{1,4})$/\1 \4/'
67.21.89.48 110
211.47.82.64 445

您可以将其运行为:

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

[0-9]{1,3}\.){3}[0-9]{1,3}可能是 IP 地址的蹩脚正则表达式,但这是我能想到的第一个。你可以用更聪明的东西代替它。也许您甚至不需要检查点之间的内容,只需在第 4 个时期之前和最后一个时期之后获取所有内容。

于 2012-04-24T21:53:28.193 回答