Regex 使用unix实用程序在同一行中匹配多个模式

Regex 使用unix实用程序在同一行中匹配多个模式,regex,awk,grep,Regex,Awk,Grep,我正试图找到这个模式匹配。我想匹配并只显示同一行中的第一个匹配项。其中一个匹配项,第四个字段可以匹配两种模式中的任何一种,即:;A、 BCD.EF或AB.CD。例如 Example 1: 12:23 23:23 ASDFGH 1,232.00 22.00 21:22 12:12 ASDSDS 22.00 21.00 预期的产出将是 Expected Result 1: 12:23 ASDFGH 1,232.00 21:22 ASDSDS 22.00 我是用我对grep和stackoverf

我正试图找到这个模式匹配。我想匹配并只显示同一行中的第一个匹配项。其中一个匹配项,第四个字段可以匹配两种模式中的任何一种,即:;A、 BCD.EF或AB.CD。例如

Example 1:
12:23 23:23 ASDFGH 1,232.00 22.00
21:22 12:12 ASDSDS 22.00 21.00 
预期的产出将是

Expected Result 1:
12:23 ASDFGH 1,232.00
21:22 ASDSDS 22.00
我是用我对grep和stackoverflow的一点了解才做到这一点的

< test_data.txt grep -one "[0-9]/[0-9][0-9]\|[0-9]*,[0-9]*.[0-9][0-9]\|[0-9]*.[0-9][0-9]" | awk -F ":" '$1 == y { sub(/[^:]:/,""); r = (r ? r OFS : "") $0; next } x { print x, r; r="" } { x=$0; y=$1; sub(/[^:]:/,"",x) } END { print x, r }'
  • 在某些行中可能有更多字段
  • 字段的顺序也不一定保留。我可以通过分别处理具有不同顺序的文件或以某种方式将它们转换为这种顺序来解决这个问题。所以这个条件可以放宽 更新2:我的问题似乎不太清楚。因此,一种方法是寻找:我在一行上找到的第一个“时间”,第一组字母数字字符串和第一个带/不带逗号的十进制值,它们都打印在同一输出行上。更一般的描述是,给定一个输入行,在输出的一行中打印第一次出现的模式1、第一次出现的模式2和第一次出现的模式3(其本身是两个模式的“或”),并且必须稳定(即,保持它们在输入中出现的顺序)。很抱歉,这是一个有点复杂的示例,我还试图了解,对于Perl/Python这样的完整语言,使用Unix实用程序是否是最好的选择。下面是第二组示例的预期结果

    Expected Result 2:
    12:21 ASADSS 11.00
    22:22 BASDASD 1,231.00
    

    Perl正则表达式风格应该可以解决这个问题:

    (\d\d:\d\d).*?([a-zA-Z]+).*?((?:\d,\d{3}\.\d\d)|(?:\d\d\.\d\d))
    
    它将捕获以下数据(处理您单独提供的每一行):

    perl script.pl示例:

    #!/usr/bin/perl
    use strict;
    use Data::Dumper;
    
    open my $F, '<', shift @ARGV;
    
    my @strings = <$F>;
    my $qr = qr/(\d\d:\d\d).*?([a-zA-Z]+).*?((?:\d,\d{3}\.\d\d)|(?:\d\d\.\d\d))/;
    
    foreach my $string (@strings) {
        chomp $string;
        next if not $string;
        my @tab = $string =~ $qr;
        print join(" ", @tab) . "\n";
    }
    

    干杯

    Perl正则表达式风格应该可以解决这个问题:

    (\d\d:\d\d).*?([a-zA-Z]+).*?((?:\d,\d{3}\.\d\d)|(?:\d\d\.\d\d))
    
    #!/usr/bin/awk -f
    
    BEGIN {
        p[0] = "^[0-9]+:[0-9]{2}$"
        p[1] = "^[[:alpha:]][[:alnum:]]*$"
        p[2] = "^[0-9]+[0-9,]*[.][0-9]{2}$"
    }
    
    {
        i = 0
        for (j = 1; j <= NF; ++j) {
            for (k = 0; k in p; ++k) {
                if ($j ~ p[k] && !q[k]++ && j > ++i) {
                    $i = $j
                }
            }
        }
        q[0] = q[1] = q[2] = 0
        NF = i
        print
    }
    
    它将捕获以下数据(处理您单独提供的每一行):

    perl script.pl示例:

    #!/usr/bin/perl
    use strict;
    use Data::Dumper;
    
    open my $F, '<', shift @ARGV;
    
    my @strings = <$F>;
    my $qr = qr/(\d\d:\d\d).*?([a-zA-Z]+).*?((?:\d,\d{3}\.\d\d)|(?:\d\d\.\d\d))/;
    
    foreach my $string (@strings) {
        chomp $string;
        next if not $string;
        my @tab = $string =~ $qr;
        print join(" ", @tab) . "\n";
    }
    
    干杯

    #!/usr/bin/awk -f
    
    BEGIN {
        p[0] = "^[0-9]+:[0-9]{2}$"
        p[1] = "^[[:alpha:]][[:alnum:]]*$"
        p[2] = "^[0-9]+[0-9,]*[.][0-9]{2}$"
    }
    
    {
        i = 0
        for (j = 1; j <= NF; ++j) {
            for (k = 0; k in p; ++k) {
                if ($j ~ p[k] && !q[k]++ && j > ++i) {
                    $i = $j
                }
            }
        }
        q[0] = q[1] = q[2] = 0
        NF = i
        print
    }
    
    输出:

    12:23 ASDFGH 1,232.00
    21:22 ASDSDS 22.00
    12:21 ASADSS 11.00
    22:22 BASDASD 1,231.00
    
    输出:

    12:23 ASDFGH 1,232.00
    21:22 ASDSDS 22.00
    12:21 ASADSS 11.00
    22:22 BASDASD 1,231.00
    

    这与仅显示字段1、3和4有何不同?你能不能展示一个更复杂的输入数据示例,让我们看看需要排除哪些内容?第二列是如何省略的?@konsolebox:我需要省略它。@但是现在前面有另一种类型的列。第二次更新会是什么样子。关于NN:NN的条件类似于NN.00和N,NNN.NN吗?请更加具体和准确,因为人们不希望由于意外的更新而不断修改他们的解决方案。@konsolebox:对不起,希望现在更清楚。这与仅显示字段1、3和4有什么区别?你能不能展示一个更复杂的输入数据示例,让我们看看需要排除哪些内容?第二列是如何省略的?@konsolebox:我需要省略它。@但是现在前面有另一种类型的列。第二次更新会是什么样子。关于NN:NN的条件类似于NN.00和N,NNN.NN吗?请更加具体和准确,因为人们不希望由于意外的更新而不断修改他们的解决方案。@konsolebox:对不起,希望它现在更清楚。我试图抵制使用一种成熟的语言,以了解单独使用Unix实用程序的最佳点。虽然awk肯定抹黑了界限:)。我试图抵制使用成熟的语言,以了解单独使用Unix实用程序的最佳点。虽然awk确实弄脏了边界:)。很好。谢谢我还用match写了一些类似的东西。但我还没有完成。再次感谢。这是一个很好的解决方案,解决了我在解析日志信息时遇到的一个令人讨厌的问题,谢谢。很好。谢谢我还用match写了一些类似的东西。但我还没有完成。再次感谢。这是一个很好的解决方案,解决了我在解析日志信息时遇到的一个令人讨厌的问题,谢谢。