Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 为什么';grep用冒号在这种模式下工作吗?_Regex_Linux_Bash_Grep_Colon - Fatal编程技术网

Regex 为什么';grep用冒号在这种模式下工作吗?

Regex 为什么';grep用冒号在这种模式下工作吗?,regex,linux,bash,grep,colon,Regex,Linux,Bash,Grep,Colon,我知道冒号:应该是文字,所以我不清楚为什么grep匹配所有行。这是一个名为“测试”的文件: 我需要将该行与::1匹配。当然,实际情况更复杂,所以我不能简单地搜索“::1”。我尝试了很多迭代,比如 grep -E '^[0-9]|[0-9]:' test grep -E '^[0-9]|[0-9]::1' test 但它们返回所有行: 123|4444 4546|4444 666666|5678 7777777|7890675::1 我希望只和最后一行匹配。知道为什么吗 这是GNU/Linux

我知道冒号:应该是文字,所以我不清楚为什么grep匹配所有行。这是一个名为“测试”的文件:

我需要将该行与::1匹配。当然,实际情况更复杂,所以我不能简单地搜索“::1”。我尝试了很多迭代,比如

grep -E '^[0-9]|[0-9]:' test
grep -E '^[0-9]|[0-9]::1' test
但它们返回所有行:

123|4444
4546|4444
666666|5678
7777777|7890675::1
我希望只和最后一行匹配。知道为什么吗


这是GNU/LinuxBash。谢谢大家!

管道需要转义,您需要允许重复的数字:

grep -E '^[0-9]+\|[0-9]+:' test
否则,
^[0-9]
需要匹配一行才能被
grep

保留。有两个问题:

  • 正则表达式
    [0-9]
    匹配任何单个数字。由于您有多个数字,因此需要将这些部件替换为与一个或多个数字匹配的
    [0-9]+
    。如果要允许无数字的空序列,请将
    +
    替换为
    *
    ,这意味着“零或更多”
  • 管道字符
    |
    在正则表达式中表示“可选”。您提供的内容将与行首的数字或后跟冒号的数字匹配。因为每一行都至少有一个,所以您可以匹配每一行。要获取文字
    字符,您可以使用
    [\124;]
    \\\
    ;在大多数样式中,第二个选项通常是首选的
  • 应用这两种方法,您可以得到
    ^[0-9]+\\\\[0-9]+::1

    给定:

    $ echo "$txt"
    123|4444
    4546|4444
    666666|5678
    7777777|7890675::1
    
    使用重复(
    +
    表示“一个或多个”)和字符类:

    $ echo "$txt" | grep -E '^[[:digit:]]+[|][[:digit:]]+[:]+'
    7777777|7890675::1
    

    由于
    \
    是一个regex元字符,因此必须将其转义(
    \\\\
    )或放在字符类中

    另一种方法是使用awk之类的工具,它可以处理每行的字段,并匹配第二个字段以“::1”结尾的行


    @ChuckPedro唉,有两个问题。
    \\\\\
    可能更受欢迎,但
    [\\]
    显然更优越:它可以被注入到更广泛的字符串类型和引用上下文中,而无需修改。@CharlesDuffy我提到了这两个问题,并将其表述为“在大多数样式中通常更可取”,尽量避免风格上的争论。有理由选择这两种方法:
    [|]
    在ERE和BRE中都可以使用,并且不需要在尽可能多的字符串中转义,但会导致不一致,因为
    [\]
    不起作用,而且可能更难阅读,因为转义的内容不太清楚。
    $ echo "$txt" | grep -E '^[[:digit:]]+[|][[:digit:]]+[:]+'
    7777777|7890675::1
    
    awk -F'|' '$2 ~ /::1$/' test