AWK使用正则表达式匹配字符串并与前一个字符串组合



我一直在回顾关于如何匹配和比较字符串的文章和帖子,但我正在努力将两者放在一起,不幸的是,我没有一个示例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-这是替换,因为我们捕获了两组,它们可以分别返回后引用12

默认的分隔符/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中测试)

相关内容

  • 没有找到相关文章

最新更新