代码之家  ›  专栏  ›  技术社区  ›  user2954003

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

  •  0
  • user2954003  · 技术社区  · 2 年前

    我一直在复习关于如何匹配和比较字符串的文章和帖子,但我很难将两者结合在一起,不幸的是,我没有一个示例awk命令,我试图使其发挥作用,因为我似乎甚至不能走那么远。下面是我一直在努力的工作,我在 comparing strings in consecutive lines with awk 我的希望是,如果我将前一行的匹配条件改为32 id以下的任何内容,开始获取一些输出,我可以尝试使用,并且我修改了NR,从第四个字符串开始,这将是第一个子网掩码。

    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地址和子网组合的数量不同

    3 回复  |  直到 2 年前
        1
  •  1
  •   Ed Morton    2 年前

    将GNU或BSD sed用于 -E 要启用ERE:

    $ sed -E 's:(\.[0-9]+)\t\t([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
    
        2
  •  0
  •   sseLtaH    2 年前

    使用 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公司 # 避免与您的 数据也将包含 / 更换后。

        3
  •  0
  •   glenn jackman    2 年前

    有了awk,这是一个更长的程序。这个使用 明确地

    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