提取具有两个或多个点的线

提取具有两个或多个点的线

我需要提取(或计算)具有两个或更多点的行(在文件中)。这些行不应以点开头(如果它们是结尾与一个点),并且不能有两个点连续(即,点都用非点字符分隔)。

输出示例:

a.b.
a.b.com
a.b.c.
a.b.c.com

但不是:

a.com
a..b
a.b.c..d

我执行了这个命令:

grep -P '^[^.]+\.([^.]+\.)+[.]+' file.txt | wc -l

但没有找到任何匹配的行。我该怎么做?

答案1

  1. \.[.]是等价的——它们都匹配一个文字点,而不是任何其他字符。就风格而言,选择一种并持续使用它。
  2. 你的问题是你的正则表达式(即模式)([^.]+\.)+后面跟着 [.]+.这实际上(某种程度上)相当于[^.]+\.后跟 [.],结果是您的 grep 正在寻找包含 的行 ,即连续两个点。如果你检查,你会发现你的命令匹配。text.text..a.b..
  3. 好的,我相信修复相当简单:
    grep -P '^[^.]+\.([^.]+\.)+[^.]*$'
    即,将 更改[.][^.](也许这就是您最初的意思?),将以下内容更改为+*并添加$.在一定数量的组之后,要求/允许除点之外的任何数量(零个或更多)字符,直到行尾。text.
  4. 一个更简单的方法(更容易理解)是
    grep -P '^[^.]+\..*\.'文件.txt | grep -v '\.\.'
    第一个grep查找以非点字符开头且至少包含两个点的行。第二个grep删除具有两个连续点的行。
  5. 与其做grep … | wc -l,不如做grep -c …

答案2

使用awk

$ cat file
.com
.c.c.c.c
a.b.
a.b.com
a.b.c.
a.b.c.com
a.com
a..b
a.b.c..d
$ awk -F . 'NF > 2 && !/^\./ && !/\.\./' file
a.b.
a.b.com
a.b.c.
a.b.c.com

这里的程序awk使用点作为字段分隔符。具有两个或多个点的线与具有两个以上场的线相同。这就是NF > 2测试所测试的。第一个正则表达式丢弃以点开头的行,第二个正则表达式丢弃连续包含两个或更多点的行。打印其余行。

同样的事情grep

grep '\..*\.' file | grep -v -e '^\.' -e '\.\.'

第一个表达式提取包含至少两个点的行,另外两个表达式删除以点开头或包含两个连续点的行。

或者与sed,

sed -n '/^\./d; /\.\./d; /\..*\./p' file

答案3

您可以通过环视来做到这一点,如下所示:

$ grep -Pc '^(?!\.)(?!.*\.\..*)(?=.*\..*\.)' file.txt

读作:

  • 我站在队伍的开头并向右看^
  • 我看到该行不是以文字点开头(?!\.)
  • 再往前看,我没有看到两个连续的文字点(?!.*\.\..*)
  • 但我确实看到了两个点,但由于在我之前的前瞻中排除了连续的点,这意味着这两个点必须由至少一个非点字符分隔(?=.*\..*\.)
  • 量子电动力学

相关内容