0

我有一个文件,如示例文件 TEST.txt 所示

TEST.txt
top.s.1 { i go to home >85

jungle.lion and city }

dog7.1.e {dalmition <101

white and black }

cars_1.3.bmw_r { very good car =10

merc is merc.r.5_two } 

我想提取以具有两个“。”的单词/字段开头的行。. 示例输出如 OUT.txt 所示

OUT.txt
 top.s.1 { i go to home >85
 dog7.1.e {dalmition <101
 cars_1.3.bmw_r { very good car =10

我尝试使用此正则表达式提取它

perl -ne '/^\w+.*?\.\w\.\d+.*?/ig && print' TEST.txt > OUT.txt

它错过了匹配几个表达式。谁能帮我得到想要的?

注意:这只是一个示例输入文件,所以这个 oneliner 可能适用于此,但它不够准确,无法在我的原始文件中找到所有字符串。

4

4 回答 4

2

您的正则表达式/^\w+.*?\.\w\.\d+.*?/ig需要一个字母数字字符串,后跟任何长度的任何内容,然后是一个点,一个字母数字,另一个点,然后是一些数字,然后是任何内容。修饰符是不必要的/i,因为模式中没有字母字符,并且/g是不必要的,因为/^/它只能匹配一次。

删除.*?并更改和更改\w\d+应该\w+可以工作。

这将满足您的要求。它期望输入文件作为命令行参数

use strict;
use warnings;

while (<>) {
  print if /^\w+\.\w+\.\w+[^\w.]/;
}

或作为命令行程序:

perl -ne 'print if /^\w+\.\w+\.\w+[^\w.]/' TEST.txt
于 2012-08-23T09:54:18.503 回答
0

awk

awk '{if ($1 ~ /.*\..*\..*/) {print}}' TEST.txt

测试在第一个字段上检查所需的模式

于 2012-08-23T09:43:39.363 回答
0

如果您的主要目标是检查块的“标题”,我认为首先将标题和块解析为哈希是一个好主意。完成后,您可以根据需要检查句点的哈希键.

> perl -MData::Dumper -nlwe 'if (/^\s*([\w.]+)\s*({\s*.*)/) { 
    $key = $1; $a{$key} = $2;
    } else { 
    $a{$key} .= $_ } }{ print Dumper \%a;' data.txt

输出:

$VAR1 = {
      'cars_1.3.bmw_r' => '{ very good car =10merc is merc.r.5_two } ',
      'top.s.1' => '{ i go to home >85jungle.lion and city }',
      'dog7.1.e' => '{ dalmition <101white and black }'
};

密钥的后处理类似于:

@keys = grep /\..*\./, keys %a;   # 2 or more periods
@keys = grep /^[^.]*\.[^.]+\.[^.]*$/, keys %a;  # exactly 2 periods

我选择使用视觉效果选项从块中删除换行符-l,但如果您认为它们应该保留,只需-l从命令行开关中删除。

于 2012-08-23T11:04:23.460 回答
-1

我会使用以下正则表达式:

perl -ne 'print if /^[^ .]*\.[^ .]*\./'

即,在行的开头可以有任何不是空格或点的东西,甚至什么都不是,然后有一个点,而不是除了空格或点之外的任何东西,然后又是一个点。

于 2012-08-23T09:51:41.370 回答