在第一次出现单词后结束匹配 - bash正则表达式

时间:2017-12-11 11:54:42

标签: regex bash regex-group

你可以帮我在bash中创建正确的正则表达式吗?

我需要做的是从结构中提取每个表定义,如:

    OID: 123
    Name: tab1
    CREATE TABLE tab1 (
       ...
       );

    OID: 456
    Name: tab2
    CREATE TABLE tab2 (
       ...
       );

    OID: 789
    Name: tab3
    CREATE TABLE tab3 (
       ...
       );

准备了一行格式:

OID: 123 Name: tab1 CREATE TABLE tab1 ( ... ); OID: 456 Name: tab2 CREATE TABLE tab2 ( ... ); OID: 789 Name: tab3 CREATE TABLE tab3 ( ... );

我必须在单词NameOID之间获取所有文字。 我写了一个简单的循环,为每个表名准备特定的正则表达式,但我遇到匹配问题。

对于每个表名,我的正则表达式如下:

(Name: tab2 .*?)( OID: .*)

我的结果是:

Name: tab2 CREATE TABLE tab2 ( ... )

我在在线正则表达式模拟器中测试了上面的正则表达式并且它正在工作。我只是从完全匹配中提取第一组。 批处理正则表达式不会正确分组。我觉得批次不知道? (前一个元素出现零次或一次)。我在bash中使用上面的正则表达式没有结果。

我的bash命令类似于:

#!/bin/bash
tables_definition=$(less tables_definition.txt)
regex="(Name: tab2 .*?)( OID: .*)"

    if [[ $tables_definition =~ $regex ]];
      then
        object_definition="${BASH_REMATCH[1]}"     

        #do something
    fi

请帮忙。

3 个答案:

答案 0 :(得分:1)

Bash的正则表达不支持"节俭量词"。

如何将grep与PCRE一起使用?

grep -Po '(?<=Name: tab. ).*?(?= OID: .*|$)'

它返回单行字符串中的所有三个定义。

答案 1 :(得分:1)

使用awk:

var data = [
  {content: '1someString', tag: 'someString', data: 'someString', author: 1},
  {content: '2someString', tag: 'someString', data: 'someString', author: 2},
  {content: '3someString', tag: 'someString', data: 'someString', author: 2},
  {content: '4someString', tag: 'someString', data: 'someString', author: 1},
]

var users = [
  {author: 1, firstName: 'aFirst', lastName: 'aLast'},
  {author: 2, firstName: 'bFirst', lastName: 'bLast'},
]

var result = users.reduce(function(r, e) {
  var name = `${e.firstName} ${e.lastName}`;
  r[name] = data.filter(a => a.author == e.author)
  .map(({content, tag, data}) => ({content, tag, data}))
  return r;
}, {})

console.log(result)

也缺少尾随换行符(由于$ awk 'BEGIN{RS="";ORS=OFS=" "}{$1=$1;print}' file OID: 123 Name: tab1 CREATE TABLE tab1 ( ... ); OID: 456 Name: tab2 CREATE TABLE tab2 ( ... ); OID: 789 Name: tab3 CREATE TABLE tab3 ( ... ); )。如果需要,请将ORS=" "添加到程序的末尾。

答案 2 :(得分:0)

Bash解决方案。输入文件包含一种行格式的表定义(不一定):

    shopt -s extglob

    table_definition=$( cat table_definition.txt )
    table_definition=${table_definition//OID: +([[:digit:]]) Name: tab+([[:digit:]] )/}
    table_definition=${table_definition//; /;\\n}

    echo -e $table_definition

第一个参数替换删除所有OID: xxx Name: tabx,第二个参数替换为所有分号添加换行符。

输出:

    CREATE TABLE tab1 ( ... );
    CREATE TABLE tab2 ( ... );
    CREATE TABLE tab3 ( ... );

如果输入文件不是oneliner,请使用

    table_definition=$( cat table_definition2.txt | tr -d "\n" | tr -s ' ')

删除换行符并对空白进行sqeeze。