在UNIX中使用cut命令获取最后一个句点

时间:2012-04-24 21:37:30

标签: unix command cut

假设我有很多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

但这只适用于一致数量的时期。有什么方法可以从后面切割?

2 个答案:

答案 0 :(得分: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}表示“一到五位”。

如果您真的注重细节,甚至可以更精确地限制数字范围,但这可能不值得。这是正则表达式处理的常见特征;你可以处理一些对手头的工作足够好的东西 - 而不必处理恶意可能给你带来的每一种可能的变化。你必须对做什么做出判断。

答案 1 :(得分: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个时段之前和最后一个时段之后取出所有内容。