从文本文件形成 IP 地址

Nas*_*eer 1 regex perl sed text-processing

我有一个巨大的文本文件,其中包含散乱的 IP 地址,但不是在一个单元中

例如。

那么@192@你到底在做什么@168@在我家@10@.你不是@16@应该在这里的。

我想要的是制作一个输出文件,并在其中制作 ipadresses 文件,如下所示

    1.192.168.10.16
    2.192.223.22.44
    etc..
Run Code Online (Sandbox Code Playgroud)

我对正则表达式有很好的理解,可以从文本文件中提取特定信息,但在这里我需要结合这些我感到困惑的地方。应该如何解决这样的问题?我正在使用 Ubuntu 12.04。

ter*_*don 6

我能想到的最简单的方法,假设你想要的数字总是用@符号分隔,是:

$ grep -oP '@\K\d+' file | perl -pe '$. % 4 != 0 && s/\n/./;'
192.168.10.16
192.169.10.16
192.128.10.16
192.162.10.16
Run Code Online (Sandbox Code Playgroud)

不过,这不会对行进行编号,因此要添加它们

$ grep -oP '@\K\d+' file | perl -pe '$. % 4 != 0 && s/\n/./;' | perl -pe 's/^/$.. /'
1. 192.168.10.16
2. 192.169.10.16
3. 192.128.10.16
4. 192.162.10.16
Run Code Online (Sandbox Code Playgroud)

解释

  • grep -oP '@\K\d+' file:-o表示“仅打印该行的匹配部分”并-Pgrep. 这让我们可以使用\d来匹配数字,最重要的是,\K这意味着“忘记你之前匹配过的任何东西”。这\K让我 grep for@\K10并且只打印 the10因为@\K.
  • perl -pe: 逐行读取输入文件,将 给出的脚本应用-e到每一行,然后打印该行 ( -p)。
  • '$. % 4 != 0 && s/\n/./;:%模运算符$.是输入文件的当前行号。该代码将取代换行符charatcer( \n)与.上是线通过4整除的结果是,因为我们喂养它号码的列表(的输出grep),每组4个数字将在相同的印刷行,因为\n被转换为..
  • perl -pe 's/^/$.. /' : 只需将当前行号添加到每行的开头即可。

Steeldriver提出了一个非常好的替代方案:

grep -oP '@\K\d+' file | xargs -n4 printf '%d.%d.%d.%d\n' | cat -n
Run Code Online (Sandbox Code Playgroud)

这让我想到了这个:

printf '%d.%d.%d.%d\n' $(grep -oP '@\K\d+' file ) | cat -n
Run Code Online (Sandbox Code Playgroud)

如果你愿意,你可以在 Perl 中完成整个事情并避免管道,但我会使用上面的方法。无论如何,始终假设您的数字被 包围@,这也将起作用:

perl -ne 'push @f,(/@(\d+)@/g); 
          END{
            $k=1;
            for($i=0;$i<=$#f;$i+=4){
                print "$k. " . join(".",@f[$i..($i+3)]) . "\n"; $k++}
            }' file
Run Code Online (Sandbox Code Playgroud)

您可以将其直接粘贴到终端中,只需更改file实际文件名即可。输出如下所示:

1. 192.168.10.16
2. 192.169.10.16
3. 192.128.10.16
4. 192.162.10.16
Run Code Online (Sandbox Code Playgroud)

解释

  • perl -ne: 逐行读取输入文件 ( -n) 并应用-e.

  • push @f,(/@(\d+)@/g);: 将每个被包围的数字保存@@f数组的一个元素。

  • END{} :在处理完所有行后执行此操作
  • for($i=0;$i<=$#f;$i+=4){}: 遍历数组。由于 IP 有 4 组数字,因此我们以四次为单位读取数组。
  • join(".",@f[$i..($i+3)]):这将连接数组的 4 个元素以.进行打印。
  • $k只是打印 IP 前面的数字。