我一直在回顾关于如何匹配和比较字符串的文章和帖子,但我正在努力将两者放在一起,不幸的是,我没有一个示例awk命令,我试图使工作,因为我似乎甚至不能得到那么远。下面是我一直在尝试使用的,我发现它在比较连续行中的字符串与awk,我的希望是,如果我从上一行更改匹配条件,而不是任何低于32 id的东西,开始得到一些我可以尝试使用的输出,并且我修改了NR以从第4个字符串开始,这将是第一个子网掩码。
awk '$0<=32 && NR>3 {print (NR)/f} {f=$0} END {print NR,$0}'
我当前的输入是这样的:
hostname1 hostname2 127.0.0.1 27 127.0.0.2 24 127.0.0.3 28 hostname3 127.0.0.4 27 127.0.0.5 24 127.0.0.6 28 127.0.0.7 27 127.0.0.8 24 127.0.0.9 28
我想要的输出是:
hostname1 hostname2 127.0.0.1/27 127.0.0.2/24 127.0.0.3/28 hostname3 127.0.0.4/27 127.0.0.5/24 127.0.0.6/28 127.0.0.7/27 127.0.0.8/24 127.0.0.9/28
这些是IP地址和子网掩码,我的想法是寻找16-32使用正则表达式,匹配前一个字符串,这将始终是一个IP地址,并结合两者。有人有任何的例子做吗?我必须使用变量,因为输入的IP地址和子网组合的数量不同
使用GNU或BSD为-E
启用EREs:
$ sed -E 's:(.[0-9]+)tt([0-9]+):1/2:g' file
hostname1 hostname2 127.0.0.1/27 127.0.0.2/24 127.0.0.3/28 hostname3 127.0.0.4/27 127.0.0.5/24 127.0.0.6/28 127.0.0.7/27 127.0.0.8/24 127.0.0.9/28
使用sed
$ sed 's#(<[[:digit:].]+)[^[:digit:]]*([[:digit:]]+)#1/2#g' input_file
hostname1 hostname2 127.0.0.1/27 127.0.0.2/24 127.0.0.3/28 hostname3 127.0.0.4/27 127.0.0.5/24 127.0.0.6/28 127.0.0.7/27 127.0.0.8/24 127.0.0.9/28
(<[[:digit:].]+)
-这是第一个捕获组,因为它被括在捕获括号内。这个捕获组将保留数字和句号。在整数匹配开始处有一个词边界<
。
[^[:digit:]]*
-排除这个匹配,因为它不在括号内,这将排除直到下一个整数字符出现的所有内容。
([[:digit:]]+)
-第二个捕获组,将保留一个或多个整数字符。
1/2
-这是替换,因为我们捕获了两组,它们可以分别返回后引用1
和2
。
默认的分隔符/
sed
已经改为#
避免冲突与你数据,替换后也将包含/
。
对于awk,它是一个较长的程序。这个用的是gawk
gawk -i join '{
n = 0
delete result
for (i=1; i<=NF; i++)
if ($i ~ /^[0-9.]+$/ && $(i+1) ~ /^[0-9]+/)
result[++n] = $i "/" $(++i)
else
result[++n] = $i
print join(result, 1, n, "t")
}' input.file
输出hostname1 hostname2 127.0.0.1/27 127.0.0.2/24 127.0.0.3/28 hostname3 127.0.0.4/27 127.0.0.5/24 127.0.0.6/28 127.0.0.7/27 127.0.0.8/24 127.0.0.9/28
我将利用GNUAWK
来完成这个任务,让file.txt
是tab分隔的文件
hostname1 hostname2 127.0.0.1 27 127.0.0.2 24 127.0.0.3 28 hostname3 127.0.0.4 27 127.0.0.5 24 127.0.0.6 28 127.0.0.7 27 127.0.0.8 24 127.0.0.9 28
然后
awk '{for(i=1;i<NF;i+=1){printf "%s%s",$i,$i~/^[0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}[.][0-9]{1,3}$/?"/":"t"};print $NF}' file.txt
给输出
hostname1 hostname2 127.0.0.1/27 127.0.0.2/24 127.0.0.3/28 hostname3 127.0.0.4/27 127.0.0.5/24 127.0.0.6/28 127.0.0.7/27 127.0.0.8/24 127.0.0.9/28
解释:我使用for
循环遍历给定live的所有字段,但最后一个字段除外。对于每个字段,我使用printf
输出该字段,然后是/
,如果它看起来像十进制IP地址(1…3位数字,点,1…3位数字,点,1…3位数,后跟点1…3位数字)或t
(TAB)字符。为了实现这个选择,我使用所谓的三元运算符condition?
valueiftrue:
valueiffalse。之后,我只是print
最后一个字段($NF
),因为它总是后跟换行符。
(在gawk 4.2.1中测试)