我有多种格式的结果
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.arpa
with <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
原理是,在空白处分割每一行输入并将结果保存在数组中。为每个调用添加一个换行符(并从输入行中删除尾随换行符),这意味着“逐行读取输入并将给定的脚本应用到每行”。perl
awk
@F
-l
print
-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