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

在UNIX中使用cut命令获取最后一个句点,unix,command,cut,Unix,Command,Cut,假设我有很多ip号码(每行2个ip号码,用空格隔开)要查看(这里有两行): 其中一个可能没有端口,因此周期数永远不一致。我只想要第一组的ip号码(不带端口),而只想要第二组的端口(不带ip号码)。所以它应该看起来像: 67.21.89.48 110 211.47.82.64 445 或者它可能看起来像这样: 67.21.89.48.110 211.47.82.64.445 cut -d'.' -f1-4,9 < file.txt 只要我知道IP和端口的位置,这并不重要 我一直在用这样

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

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

67.21.89.48 110
211.47.82.64 445
或者它可能看起来像这样:

67.21.89.48.110
211.47.82.64.445
cut -d'.' -f1-4,9 < file.txt
只要我知道IP和端口的位置,这并不重要

我一直在用这样的东西:

67.21.89.48.110
211.47.82.64.445
cut -d'.' -f1-4,9 < file.txt
cut-d'.-f1-4,9
但这只适用于持续时间。有没有办法从后面剪下来?

详细格式:

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地址):

我用
\d+
表示“一个或多个数字”;对于IPv4虚线十进制地址组件,对于“一到三位数”,可以将其转换为
\d{1,3}
,对于“一到五位数”,端口号可以是
\d{1,5}

如果你真的注重细节,你甚至可以更精确地限制数字范围,但这可能不值得。这是正则表达式处理的一个常见特征;你做的事情足以胜任手头的工作,而不必处理恶意软件可能对你造成的每一种可能的变化。你必须对该做什么做出判断。

详细格式:

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地址):

我用
\d+
表示“一个或多个数字”;对于IPv4虚线十进制地址组件,对于“一到三位数”,可以将其转换为
\d{1,3}
,对于“一到五位数”,端口号可以是
\d{1,5}


如果你真的注重细节,你甚至可以更精确地限制数字范围,但这可能不值得。这是正则表达式处理的一个常见特征;你做的事情足以胜任手头的工作,而不必处理恶意软件可能对你造成的每一种可能的变化。你必须做出判断。正如乔纳森在评论中指出的那样,使用
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地址的蹩脚正则表达式,但这是我能想到的第一个。你可以用更聪明的东西来代替它。
也许你甚至不需要检查点之间的内容,只需要在第四个句号之前和最后一个句号之后取下所有内容。

正如乔纳森在评论中指出的那样,使用
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地址的蹩脚正则表达式,但这是我能想到的第一个。你可以用更聪明的东西来代替它。
也许你甚至不需要检查点之间的内容,只需要在第四节课之前和最后一节课之后检查所有内容。

不是标准的,不。我认为你需要使用不同的工具来完成这项工作。您的选择很多,包括
sed
awk
perl
python
,可能还有更多。第二个地址是否保证有端口号?您是否可以控制IP地址/端口号的格式?在IP地址和端口号之间放一个冒号(而不是用句点分隔地址和端口)将更容易解析。不是标准的,不是。我认为你需要使用不同的工具来完成这项工作。您的选择很多,包括
sed
awk
perl
python
,可能还有更多。第二个地址是否保证有端口号?您是否可以控制IP地址/端口号的格式?在IP地址和端口号之间放一个冒号(而不是用句点分隔地址和端口)将更容易解析。