Bash,从用点分隔的字符串中截断 IP

Bash,从用点分隔的字符串中截断 IP

我有多种格式的结果

10.3.2.1.in-addr.arpa name hostname

我想删除中间部分“.in-addr.arpa”并将IP地址反转为例如1.2.3.10。用一个简单的 bash oneliner 就可以做到这一点吗?预先感谢,我几个小时以来一直在尝试这样做,但有点卡住了。

答案1

perl

perl -pe 's/(\d+)\.(\d+)\.(\d+)\.(\d+)\.in-addr\.arpa/$4.$3.$2.$1/g' < input

与标准等效内容相比,它更简洁,更易读sed

d='\([0-9]\{1,\}\)'
LC_ALL=C sed "s/$d\.$d\.$d\.$d\.in-addr\.arpa/\4.\3.\2.\1/g" < input

这些将替换所有出现的<d1>.<d2>.<d3>.<d4>.in-addr.arpawith <d4>.<d3>.<d2>.<d1>(其中<dX>是一个或多个十进制数字的任意序列),而其他所有内容均保持不变。

答案2

$ awk '{split($1,p,"."); $1=p[4]"."p[3]"."p[2]"."p[1]} 1' file
1.2.3.10 name hostname

答案3

另一种 perl 方法:

$ perl -lane '@ip=split(/\./,$F[0]); $F[0]=join(".",reverse(@ip[0..3])); print "@F"' file
1.2.3.10 name hostname

请注意,这假设.该行的前 4 个分隔元素是 IP 地址。

解释

  • -lane:该命令的工作-a原理是,在空白处分割每一行输入并将结果保存在数组中。为每个调用添加一个换行符(并从输入行中删除尾随换行符),这意味着“逐行读取输入并将给定的脚本应用到每行”。perlawk@F-lprint-n-e
  • @ip=split(/\./,$F[0]):获取第一个字段 ( $F[0]) 并将其拆分.,将输出保存在数组中@ip
  • $F[0]=join(".",reverse(@ip[0..3]));: 这个有几个部分。首先,join(CHAR, ARRAY)将使用字符 CHAR 将 ARRAY 的元素连接成字符串。在这里,我们传递数组的前 4 个元素(索引 0 到 3)@ip,因此直到示例中的非数字为止的所有元素,因此连接将生成 IP。接下来,reverse将其反转。最后,我们将结果保存为$F[0].
  • print "@F":经过前面的步骤后,@F数组现在包含我们想要的内容,因此我们将其打印出来。

如果您想要的只是从输入文件的所有行中删除第一次出现的字符串.in-addr.arpa,然后反转 IP,您可以这样做:

$ perl -pe 's/\.in-addr\.arpa//; s/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/$4.$3.$2.$1/' file
1.2.3.10 name hostname

答案4

另一种方法是利用正则表达式中内置的循环/扫描字符串我们在正则表达式中设置回溯,并在回溯到开头时停止。

$ perl -lne '
    m/(.*) ((?<!\d)\d+\.) (?{printf q(%s), $1?$2:$2=~s|\.||r}) (?(?{$1 ne ""}) (?!))/x;
    print /(\s\S.*)/;
' file
1.2.3.10 name hostname

相关内容