假设我有很多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但这只适用于固定数量的周期。有没有办法从后面剪下来呢?
发布于 2012-04-25 05:53:28
正如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地址正则表达式,但它是我能想到的第一个。你可以用更聪明的东西来代替它。也许你甚至不需要检查点之间是什么,只需要取第四节之前和最后一节之后的所有内容。
发布于 2012-04-25 05:42:59
详细格式:
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}。
如果你真的很注重细节,你甚至可以更精确地限制数字范围,但这可能是不值得的。这是正则表达式处理的一个常见特性;您可以做一些对手头的工作足够好的工作,而不必处理恶意程序可能抛给您的每一个可能的变化。你必须对该做什么做出判断。
https://stackoverflow.com/questions/10306375
复制相似问题